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
13 changes: 12 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,14 @@
"/integrations/integration-guides/plus-google-analytics",
"/integrations/integration-guides/googlecalendar",
"/integrations/integration-guides/gsheets",
"/integrations/integration-guides/hitl",
{
"group": "HITL",
"icon": "/integrations/integration-guides/assets/icons/hitl.svg",
"pages": [
"/integrations/integration-guides/hitl/introduction",
"/integrations/integration-guides/hitl/time-to-first-agent-response"
]
},
"/integrations/integration-guides/hubspot",
"/integrations/integration-guides/hunter",
"/integrations/integration-guides/improvement",
Expand Down Expand Up @@ -650,6 +657,10 @@
{
"source": "/integrations/functional-integrations/:slug*",
"destination": "/integrations/integration-guides/:slug*"
},
{
"source": "/integrations/integration-guides/hitl",
"destination": "/integrations/integration-guides/hitl/introduction"
}
],
"integrations": {
Expand Down
2 changes: 1 addition & 1 deletion get-started/manage-your-agent/human-handoff.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ If you want to allow a live agent to join your agent's conversations, you can co

To get started using Human Handoff, you need to install and configure the official Human-in-the-Loop (HITL) integration:

<Card title="Configure HITL" href="/integrations/integration-guides/hitl" icon="plug" horizontal>
<Card title="Configure HITL" href="/integrations/integration-guides/hitl/introduction" icon="plug" horizontal>
Install and configure the official integration <Tooltip tip="This feature requires a Botpress Plus plan or higher."><Badge stroke color="blue">Plus</Badge></Tooltip>
</Card>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
---
title: Human-in-the-Loop (HITL)
description: >-
Allow a live agent to participate directly in the bot's
conversation.
icon: '/integrations/integration-guides/assets/icons/hitl.svg'
description: Allow a live agent to participate directly in the bot's conversation.
sidebarTitle: Setup
---

{/* vale off */}
Expand Down Expand Up @@ -90,12 +88,12 @@ First, install the official HITL integration:
<img
alt="Start HITL Card"
className="block dark:hidden"
src="./assets/start-hitl-card.png"
src="../assets/start-hitl-card.png"
/>
<img
alt="Start HITL Card"
className="hidden dark:block"
src="./assets/start-hitl-card-dark.png"
src="../assets/start-hitl-card-dark.png"
/>
</Frame>
</Step>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Measure HITL Response Time
description: Measure the Time to First Agent Response for conversations in HITL.
sidebarTitle: Measure HITL Response Time
---

## Prerequisites

<Info>
You will need:

- A [Botpress Plus plan](https://botpress.com/pricing) or higher
- The [HITL integration and plugin configured](/integrations/integration-guides/hitl/introduction) so agents can join conversations
</Info>

This guide explains how to measure the **Time to First Agent Response** for conversations handed off to a human agent via [Human-in-the-Loop (HITL)](/integrations/integration-guides/hitl/introduction). The metric captures how long a user waited from the moment they requested a human agent to the moment an agent was assigned.

The result is stored as a formatted string in a conversation variable and can be sent using a [Text Card](/studio/concepts/cards/send-messages#text), [sent to an external system](/studio/concepts/cards/execute-code), or [saved to a Botpress table](/studio/concepts/cards/tables#insert-record).

## 1. Create conversation variables

Create the following two variables in your bot, scoped as **Conversation** variables:

| Variable Name | Type | Description |
| :---------------------- | :----- | :----------------------------------------------------- |
| `hitlRequestTimestamp` | number | Unix timestamp (ms) of when the HITL request was made |
| `hitlTimingDisplay` | string | Formatted summary string of the timing result |

In Botpress Studio, go to **Variables** → **+ New Variable**, set the scope to **Conversation**, and configure each entry as described above.

## 2. Capture the request timestamp

Before your [Start HITL](/integrations/integration-guides/hitl/introduction#step-3-add-the-start-hitl-card-to-your-workflow) Card, insert an [Execute Code](/studio/concepts/cards/execute-code) Card that records when the user was handed off to HITL. Use the following code:

```js
conversation.hitlRequestTimestamp = Date.now()
```

This stores the exact moment the user was handed off to HITL, in milliseconds since the [Unix Epoch](https://en.wikipedia.org/wiki/Unix_time).

<Info title="Unix Epoch">
The **Unix Epoch** is January 1, 1970 at 00:00:00 UTC. Timestamps in "milliseconds since the Unix epoch" are the number of milliseconds elapsed since that moment.
</Info>

## 3. Calculate and format the wait time

After your [Start HITL](/integrations/integration-guides/hitl/introduction#step-3-add-the-start-hitl-card-to-your-workflow) Card, insert another [Execute Code](/studio/concepts/cards/execute-code) Card that computes the time until an agent was assigned and formats the result. Use the following code:

```js
const { conversation: upstream } = await client.getConversation({ id: event.conversationId })
const downstreamConvId = upstream.tags?.['hitl#downstream']

if (downstreamConvId) {
const { conversation: downstream } = await client.getConversation({ id: downstreamConvId })
const assignedAtMs = parseInt(downstream.tags?.['hitl:assignedAt'] || '0')

if (assignedAtMs) {
const requestTime = new Date(conversation.hitlRequestTimestamp)
const assignedTime = new Date(assignedAtMs)

const diffMs = assignedAtMs - Number(conversation.hitlRequestTimestamp)
const diffMins = Math.floor(diffMs / 60000)
const diffSecs = Math.floor((diffMs % 60000) / 1000)

const fmt = (d) =>
d.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true,
timeZone: 'America/New_York'
})

conversation.hitlTimingDisplay =
`HITL Request Time: ${fmt(requestTime)}\n` +
`HITL Assignment Time: ${fmt(assignedTime)}\n` +
`Wait Time: ${diffMins}m ${diffSecs}s`
}
}
```

What this code does:

- Fetches the upstream conversation using the current conversation ID.
- Resolves the downstream HITL conversation via the `hitl#downstream` tag (set automatically by Botpress when a handoff is initiated).
- Reads the `hitl:assignedAt` tag from the downstream conversation (timestamp of when an agent accepted and assigned).
- Computes the wait time between the request and assignment.
- Formats and stores the result in `conversation.hitlTimingDisplay`.

Once the code runs, `conversation.hitlTimingDisplay` will contain a message in this format:

```
HITL Request Time: 8:28:07 PM
HITL Assignment Time: 8:28:31 PM
Wait Time: 0m 24s
```

<Note>
Times are displayed in the America/New_York timezone. Update the `timeZone` value in the `fmt` function if your team operates in a different timezone.
</Note>

## 4. Use the data

The `conversation.hitlTimingDisplay` variable is available for the rest of your Workflow. You can:

- **Display it in chat**: Add a [Text](/studio/concepts/cards/send-messages#text) Card and reference `{{conversation.hitlTimingDisplay}}` to send the summary to the conversation (useful for testing and QA).
- **Log it to a Botpress Table**: Use an [Update Table Row](/studio/concepts/cards/tables#update-record) or [Insert Table Row](/studio/concepts/cards/tables#insert-record) Card to persist the data for reporting.
- **Send it to an external system**: Use an [Execute Code](/studio/concepts/cards/execute-code) Card with an `axios` or `fetch` call to forward the values to your analytics platform, CRM, or data warehouse.

<Check>
You can now measure Time to First Agent Response for HITL conversations and use the result in your bot Workflows, tables, or external systems.
</Check>
2 changes: 1 addition & 1 deletion studio/concepts/agents/hitl-agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Allows human intervention in the bot's conversations and decision-m
---

<Warning>
The Human-in-the-loop (HITL) Agent is **deprecated** and is no longer available to new accounts. Please use the [HITL Plugin](/integrations/integration-guides/hitl) instead.
The Human-in-the-loop (HITL) Agent is **deprecated** and is no longer available to new accounts. Please use the [HITL Plugin](/integrations/integration-guides/hitl/introduction) instead.

If you have a HITL Agent enabled, it will remain available for the time being. However, if you disable the Agent, you won't be able to restore it.
</Warning>
Expand Down
2 changes: 1 addition & 1 deletion studio/concepts/nodes/autonomous-node.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ You can view a full list of tools your bot currently has access to in the [Inspe
<Accordion
title="Example: HITL integration"
>
This prompt tells the Autonomous Node to start a [Human-in-the-loop (HITL)](/integrations/integration-guides/hitl) session when the user indicates they'd like to speak to a live agent:
This prompt tells the Autonomous Node to start a [Human-in-the-loop (HITL)](/integrations/integration-guides/hitl/introduction) session when the user indicates they'd like to speak to a live agent:

```markdown Instructions wrap
When the user indicates they'd like to speak to a live agent, use `hitl.startHitl`.
Expand Down
Loading