-
+
{node.children.map((child) => (
))}
@@ -126,26 +132,31 @@ function ChildNode({
node,
currentPath,
textSize = 'sm',
- nested = false,
+ depth = 0,
}: {
node: SidebarNode
currentPath: string
textSize?: 'sm' | 'base'
- nested?: boolean
+ depth?: number
}) {
if (node.type === 'category') {
- return
+ return
}
const active = isPathActive(node.href, currentPath)
+ const pad = PAD[depth] ?? PAD[PAD.length - 1]
+ const activeLine =
+ depth === 1
+ ? ' relative before:absolute before:left-2.5 before:top-2 before:bottom-2 before:w-px before:bg-primary'
+ : ''
return (
-
@@ -177,6 +188,7 @@ export default function SidebarTreeView({ nodes, currentPath, textSize = 'sm' }:
node={child}
currentPath={currentPath}
textSize={textSize}
+ depth={0}
/>
))}
@@ -186,7 +198,7 @@ export default function SidebarTreeView({ nodes, currentPath, textSize = 'sm' }:
return (
)
})}
diff --git a/public/assets/get-started/home-dark.png b/src/content/docs/get-started/assets/home-dark.png
similarity index 100%
rename from public/assets/get-started/home-dark.png
rename to src/content/docs/get-started/assets/home-dark.png
diff --git a/public/assets/get-started/home.png b/src/content/docs/get-started/assets/home.png
similarity index 100%
rename from public/assets/get-started/home.png
rename to src/content/docs/get-started/assets/home.png
diff --git a/public/assets/get-started/usage-dark.png b/src/content/docs/get-started/assets/usage-dark.png
similarity index 100%
rename from public/assets/get-started/usage-dark.png
rename to src/content/docs/get-started/assets/usage-dark.png
diff --git a/public/assets/get-started/usage.png b/src/content/docs/get-started/assets/usage.png
similarity index 100%
rename from public/assets/get-started/usage.png
rename to src/content/docs/get-started/assets/usage.png
diff --git a/src/content/docs/get-started/configure-your-workspace.mdx b/src/content/docs/get-started/configure-your-workspace.mdx
index 0d5951e..b2efbd2 100644
--- a/src/content/docs/get-started/configure-your-workspace.mdx
+++ b/src/content/docs/get-started/configure-your-workspace.mdx
@@ -3,6 +3,12 @@ title: Configure your workspace
description: Manage agents, billing, usage quotas, and member roles in your Botpress workspace.
---
+import { Picture } from 'astro:assets'
+import homeDarkImg from './assets/home-dark.png'
+import homeImg from './assets/home.png'
+import usageDarkImg from './assets/usage-dark.png'
+import usageImg from './assets/usage.png'
+
import { Note, Tip } from '@/components/callouts'
import Steps from '@/components/Steps.astro'
import Step from '@/components/Step.astro'
@@ -39,8 +45,8 @@ To add a new workspace:
You can manage all your agents in your workspace's **
Home** menu:
-

-

+
+
### Create a new agent
@@ -96,8 +102,8 @@ To learn more about building and deploying your own integrations:
You can track information about usage across your workspace in the **
Usage** menu.
-

-

+
+
This page contains a breakdown of each type of usage quota.
diff --git a/public/assets/manage-your-agent/access-control-dark.png b/src/content/docs/get-started/manage-your-agent/assets/access-control-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/access-control-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/access-control-dark.png
diff --git a/public/assets/manage-your-agent/access-control.png b/src/content/docs/get-started/manage-your-agent/assets/access-control.png
similarity index 100%
rename from public/assets/manage-your-agent/access-control.png
rename to src/content/docs/get-started/manage-your-agent/assets/access-control.png
diff --git a/public/assets/manage-your-agent/ai-insights-dark.png b/src/content/docs/get-started/manage-your-agent/assets/ai-insights-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/ai-insights-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/ai-insights-dark.png
diff --git a/public/assets/manage-your-agent/ai-insights.png b/src/content/docs/get-started/manage-your-agent/assets/ai-insights.png
similarity index 100%
rename from public/assets/manage-your-agent/ai-insights.png
rename to src/content/docs/get-started/manage-your-agent/assets/ai-insights.png
diff --git a/public/assets/manage-your-agent/analytics-dark.png b/src/content/docs/get-started/manage-your-agent/assets/analytics-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/analytics-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/analytics-dark.png
diff --git a/public/assets/manage-your-agent/analytics.png b/src/content/docs/get-started/manage-your-agent/assets/analytics.png
similarity index 100%
rename from public/assets/manage-your-agent/analytics.png
rename to src/content/docs/get-started/manage-your-agent/assets/analytics.png
diff --git a/public/assets/manage-your-agent/assign-conversation-dark.png b/src/content/docs/get-started/manage-your-agent/assets/assign-conversation-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/assign-conversation-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/assign-conversation-dark.png
diff --git a/public/assets/manage-your-agent/assign-conversation.png b/src/content/docs/get-started/manage-your-agent/assets/assign-conversation.png
similarity index 100%
rename from public/assets/manage-your-agent/assign-conversation.png
rename to src/content/docs/get-started/manage-your-agent/assets/assign-conversation.png
diff --git a/public/assets/manage-your-agent/conversation-dark.png b/src/content/docs/get-started/manage-your-agent/assets/conversation-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/conversation-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/conversation-dark.png
diff --git a/public/assets/manage-your-agent/conversation.png b/src/content/docs/get-started/manage-your-agent/assets/conversation.png
similarity index 100%
rename from public/assets/manage-your-agent/conversation.png
rename to src/content/docs/get-started/manage-your-agent/assets/conversation.png
diff --git a/public/assets/manage-your-agent/event-json-data-dark.png b/src/content/docs/get-started/manage-your-agent/assets/event-json-data-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/event-json-data-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/event-json-data-dark.png
diff --git a/public/assets/manage-your-agent/event-json-data.png b/src/content/docs/get-started/manage-your-agent/assets/event-json-data.png
similarity index 100%
rename from public/assets/manage-your-agent/event-json-data.png
rename to src/content/docs/get-started/manage-your-agent/assets/event-json-data.png
diff --git a/public/assets/manage-your-agent/events-dark.png b/src/content/docs/get-started/manage-your-agent/assets/events-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/events-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/events-dark.png
diff --git a/public/assets/manage-your-agent/events.png b/src/content/docs/get-started/manage-your-agent/assets/events.png
similarity index 100%
rename from public/assets/manage-your-agent/events.png
rename to src/content/docs/get-started/manage-your-agent/assets/events.png
diff --git a/public/assets/manage-your-agent/file-json-data-dark.png b/src/content/docs/get-started/manage-your-agent/assets/file-json-data-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/file-json-data-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/file-json-data-dark.png
diff --git a/public/assets/manage-your-agent/file-json-data.png b/src/content/docs/get-started/manage-your-agent/assets/file-json-data.png
similarity index 100%
rename from public/assets/manage-your-agent/file-json-data.png
rename to src/content/docs/get-started/manage-your-agent/assets/file-json-data.png
diff --git a/public/assets/manage-your-agent/issue-events-dark.png b/src/content/docs/get-started/manage-your-agent/assets/issue-events-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/issue-events-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/issue-events-dark.png
diff --git a/public/assets/manage-your-agent/issue-events.png b/src/content/docs/get-started/manage-your-agent/assets/issue-events.png
similarity index 100%
rename from public/assets/manage-your-agent/issue-events.png
rename to src/content/docs/get-started/manage-your-agent/assets/issue-events.png
diff --git a/public/assets/manage-your-agent/issues-dark.png b/src/content/docs/get-started/manage-your-agent/assets/issues-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/issues-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/issues-dark.png
diff --git a/public/assets/manage-your-agent/issues.png b/src/content/docs/get-started/manage-your-agent/assets/issues.png
similarity index 100%
rename from public/assets/manage-your-agent/issues.png
rename to src/content/docs/get-started/manage-your-agent/assets/issues.png
diff --git a/public/assets/manage-your-agent/logs-dark.png b/src/content/docs/get-started/manage-your-agent/assets/logs-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/logs-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/logs-dark.png
diff --git a/public/assets/manage-your-agent/logs.png b/src/content/docs/get-started/manage-your-agent/assets/logs.png
similarity index 100%
rename from public/assets/manage-your-agent/logs.png
rename to src/content/docs/get-started/manage-your-agent/assets/logs.png
diff --git a/public/assets/manage-your-agent/message-json-data-dark.png b/src/content/docs/get-started/manage-your-agent/assets/message-json-data-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/message-json-data-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/message-json-data-dark.png
diff --git a/public/assets/manage-your-agent/message-json-data.png b/src/content/docs/get-started/manage-your-agent/assets/message-json-data.png
similarity index 100%
rename from public/assets/manage-your-agent/message-json-data.png
rename to src/content/docs/get-started/manage-your-agent/assets/message-json-data.png
diff --git a/public/assets/manage-your-agent/pending-conversation-dark.png b/src/content/docs/get-started/manage-your-agent/assets/pending-conversation-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/pending-conversation-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/pending-conversation-dark.png
diff --git a/public/assets/manage-your-agent/pending-conversation.png b/src/content/docs/get-started/manage-your-agent/assets/pending-conversation.png
similarity index 100%
rename from public/assets/manage-your-agent/pending-conversation.png
rename to src/content/docs/get-started/manage-your-agent/assets/pending-conversation.png
diff --git a/public/assets/manage-your-agent/preview-dark.png b/src/content/docs/get-started/manage-your-agent/assets/preview-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/preview-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/preview-dark.png
diff --git a/public/assets/manage-your-agent/preview.png b/src/content/docs/get-started/manage-your-agent/assets/preview.png
similarity index 100%
rename from public/assets/manage-your-agent/preview.png
rename to src/content/docs/get-started/manage-your-agent/assets/preview.png
diff --git a/public/assets/manage-your-agent/respond-to-user-dark.png b/src/content/docs/get-started/manage-your-agent/assets/respond-to-user-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/respond-to-user-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/respond-to-user-dark.png
diff --git a/public/assets/manage-your-agent/respond-to-user.png b/src/content/docs/get-started/manage-your-agent/assets/respond-to-user.png
similarity index 100%
rename from public/assets/manage-your-agent/respond-to-user.png
rename to src/content/docs/get-started/manage-your-agent/assets/respond-to-user.png
diff --git a/public/assets/manage-your-agent/trigger-human-handoff-dark.png b/src/content/docs/get-started/manage-your-agent/assets/trigger-human-handoff-dark.png
similarity index 100%
rename from public/assets/manage-your-agent/trigger-human-handoff-dark.png
rename to src/content/docs/get-started/manage-your-agent/assets/trigger-human-handoff-dark.png
diff --git a/public/assets/manage-your-agent/trigger-human-handoff.png b/src/content/docs/get-started/manage-your-agent/assets/trigger-human-handoff.png
similarity index 100%
rename from public/assets/manage-your-agent/trigger-human-handoff.png
rename to src/content/docs/get-started/manage-your-agent/assets/trigger-human-handoff.png
diff --git a/src/content/docs/get-started/manage-your-agent/control-access.mdx b/src/content/docs/get-started/manage-your-agent/control-access.mdx
index 8c1c662..cb997c1 100644
--- a/src/content/docs/get-started/manage-your-agent/control-access.mdx
+++ b/src/content/docs/get-started/manage-your-agent/control-access.mdx
@@ -3,6 +3,10 @@ title: Control access to your agent
description: Restrict which workspace members can access your agent.
---
+import { Picture } from 'astro:assets'
+import accessControlDarkImg from './assets/access-control-dark.png'
+import accessControlImg from './assets/access-control.png'
+
import { Info, Note } from '@/components/callouts'
import Steps from '@/components/Steps.astro'
import Step from '@/components/Step.astro'
@@ -24,8 +28,8 @@ If you're an owner or administrator in your workspace, you can restrict who in y
Here, you can select which members of your Workspace have access to your agent:
-

-

+
+
When you're done, select **Save**.
diff --git a/src/content/docs/get-started/manage-your-agent/human-handoff.mdx b/src/content/docs/get-started/manage-your-agent/human-handoff.mdx
index c09d850..f77e5f5 100644
--- a/src/content/docs/get-started/manage-your-agent/human-handoff.mdx
+++ b/src/content/docs/get-started/manage-your-agent/human-handoff.mdx
@@ -3,6 +3,16 @@ title: Configure Human Handoff
description: Set up live agent support with the Human-in-the-Loop integration.
---
+import { Picture } from 'astro:assets'
+import assignConversationDarkImg from './assets/assign-conversation-dark.png'
+import assignConversationImg from './assets/assign-conversation.png'
+import pendingConversationDarkImg from './assets/pending-conversation-dark.png'
+import pendingConversationImg from './assets/pending-conversation.png'
+import respondToUserDarkImg from './assets/respond-to-user-dark.png'
+import respondToUserImg from './assets/respond-to-user.png'
+import triggerHumanHandoffDarkImg from './assets/trigger-human-handoff-dark.png'
+import triggerHumanHandoffImg from './assets/trigger-human-handoff.png'
+
import { Tip } from '@/components/callouts'
import Steps from '@/components/Steps.astro'
import Step from '@/components/Step.astro'
@@ -40,12 +50,8 @@ When you've finished setting up the integration, you'll have access to the Human
When a user triggers Human Handoff, a ticket is opened. You can view your tickets in the left sidebar:
-

-

+
+
Select any ticket to view the conversation with the user.
@@ -57,19 +63,15 @@ Select any ticket to view the conversation with the user.
You can assign a ticket to anyone in your Workspace, including yourself. For example, select **
Assign to me**:
-

-

+
+
Now you can chat directly with the user:
-

-

+
+
### Close a ticket
@@ -88,15 +90,15 @@ You can test Human Handoff by using your agent's preview to simulate an escalati
Chat with your agent until it triggers Human Handoff:
-

-

diff --git a/src/content/docs/get-started/manage-your-agent/inspect.mdx b/src/content/docs/get-started/manage-your-agent/inspect.mdx
index 949f538..326243a 100644
--- a/src/content/docs/get-started/manage-your-agent/inspect.mdx
+++ b/src/content/docs/get-started/manage-your-agent/inspect.mdx
@@ -3,6 +3,20 @@ title: Inspect behaviour
description: View logs, events, files, and errors to debug your agent's behaviour.
---
+import { Picture } from 'astro:assets'
+import eventJsonDataDarkImg from './assets/event-json-data-dark.png'
+import eventJsonDataImg from './assets/event-json-data.png'
+import eventsDarkImg from './assets/events-dark.png'
+import eventsImg from './assets/events.png'
+import fileJsonDataDarkImg from './assets/file-json-data-dark.png'
+import fileJsonDataImg from './assets/file-json-data.png'
+import issueEventsDarkImg from './assets/issue-events-dark.png'
+import issueEventsImg from './assets/issue-events.png'
+import issuesDarkImg from './assets/issues-dark.png'
+import issuesImg from './assets/issues.png'
+import logsDarkImg from './assets/logs-dark.png'
+import logsImg from './assets/logs.png'
+
import Icon from '@/components/Icon.astro'
import Frame from '@/components/Frame.astro'
@@ -13,8 +27,8 @@ You can inspect your agent's behaviour in the **
Inspect** sec
You can view logs from all your agent's conversations in the **Logs** sub-section. This includes system logs that provide updates on your agent's status, as well as logs from any integrations you have installed:
-

-

+
+
You can filter logs by date and time to narrow down your search for a specific event or conversation.
@@ -36,8 +50,8 @@ Once you've published your changes, your bot will print that statement to its lo
Events represent anything that happens within the bot, such as messages from users, bot replies, and system-level occurrences. You can view all incoming events processed by your agent in the **Events** section:
-

-

+
+
### Event data
@@ -45,8 +59,8 @@ Events represent anything that happens within the bot, such as messages from use
Select any event to view a detailed JSON representation of all its associated data:
-

-

+
+
### Quota
@@ -69,8 +83,8 @@ You can view all files uploaded to your agent in the **Files** section. This inc
Select any file to view a detailed JSON representation of all its associated data:
-

-

+
+
### View a file
@@ -96,15 +110,15 @@ Any files you store count against your File Storage quota. You can increase your
You can view any problems or errors your agent encountered in the **Issues** sub-section:
-

-

+
+
The **Category** field tells you where the issue came from, while the **Events** field tells you how many times it occurred. Select any issue to view a list of all occurrences:
-

-

+
+
This gives you detailed information about each occurrence, like:
diff --git a/src/content/docs/get-started/manage-your-agent/monitor.mdx b/src/content/docs/get-started/manage-your-agent/monitor.mdx
index 51b113d..bf22823 100644
--- a/src/content/docs/get-started/manage-your-agent/monitor.mdx
+++ b/src/content/docs/get-started/manage-your-agent/monitor.mdx
@@ -3,6 +3,16 @@ title: Monitor performance
description: Track conversations, users, and performance analytics for your agent.
---
+import { Picture } from 'astro:assets'
+import aiInsightsDarkImg from './assets/ai-insights-dark.png'
+import aiInsightsImg from './assets/ai-insights.png'
+import analyticsDarkImg from './assets/analytics-dark.png'
+import analyticsImg from './assets/analytics.png'
+import conversationDarkImg from './assets/conversation-dark.png'
+import conversationImg from './assets/conversation.png'
+import messageJsonDataDarkImg from './assets/message-json-data-dark.png'
+import messageJsonDataImg from './assets/message-json-data.png'
+
import Icon from '@/components/Icon.astro'
import Frame from '@/components/Frame.astro'
import { Badge } from '@/components/ui/badge'
@@ -14,8 +24,8 @@ You can monitor your agent's performance in the **
Mon
You can view a list of all your agent's conversations in the **Conversations** sub-section. Just select any conversation to view its details:
-

-

+
+
In this menu, you can access:
@@ -32,8 +42,8 @@ In this menu, you can access:
You can select any message in the conversation to get a detailed JSON representation of all its associated data:
-

-

+
+
### AI insights {
BETA}
@@ -41,8 +51,8 @@ You can select any message in the conversation to get a detailed JSON representa
Select **
Enable AI** to enable sentiment analysis and AI summaries for incoming conversations:
-

-

+
+
---
@@ -56,8 +66,8 @@ You can view all your agent's unique users in the **Users** sub-section. Select
You can view detailed analytics about your agent's performance in the **Analytics** sub-section:
-

-

+
+
For any tile, you can:
diff --git a/src/content/docs/get-started/manage-your-agent/preview.mdx b/src/content/docs/get-started/manage-your-agent/preview.mdx
index 24e8d5d..dad5534 100644
--- a/src/content/docs/get-started/manage-your-agent/preview.mdx
+++ b/src/content/docs/get-started/manage-your-agent/preview.mdx
@@ -3,6 +3,10 @@ title: Preview
description: Test your published agent's behaviour using the built-in preview.
---
+import { Picture } from 'astro:assets'
+import previewDarkImg from './assets/preview-dark.png'
+import previewImg from './assets/preview.png'
+
import Steps from '@/components/Steps.astro'
import Step from '@/components/Step.astro'
import Icon from '@/components/Icon.astro'
@@ -27,8 +31,8 @@ You can chat with a preview of your published agent at any time:
Start a conversation with your agent and test its behaviour:
-

-

+
+
## Styling
diff --git a/src/content/docs/get-started/quick-start.mdx b/src/content/docs/get-started/quick-start.mdx
index b5eb4e7..48105d4 100644
--- a/src/content/docs/get-started/quick-start.mdx
+++ b/src/content/docs/get-started/quick-start.mdx
@@ -31,8 +31,8 @@ By the end of this guide, you'll have a bot that:
- If you'd prefer to set your bot up from scratch, hit **Skip** and head over to the
- [tutorial](/tutorial/introduction)—we'll show you how to start building with Botpress Studio.
+ If you'd prefer to set your bot up from scratch, hit **Skip** and head over to the [tutorial](/tutorial)—we'll show
+ you how to start building with Botpress Studio.
## Step 2: Fine-tune your bot (Optional)
@@ -69,7 +69,7 @@ You can do this with [Botpress Studio](/studio/introduction), our agent-building
title="Tutorial"
icon="ChefHat"
horizontal
- href="/tutorial/introduction"
+ href="/tutorial"
>
Learn the basics of Botpress Studio by building a bot
diff --git a/src/content/docs/studio/concepts/actions.mdx b/src/content/docs/studio/concepts/actions.mdx
new file mode 100644
index 0000000..7dbf995
--- /dev/null
+++ b/src/content/docs/studio/concepts/actions.mdx
@@ -0,0 +1,154 @@
+---
+title: Actions
+icon: Bolt
+---
+
+import { Picture } from 'astro:assets'
+import actionPromptDarkImg from './assets/action-prompt-dark.png'
+import actionPromptExampleDarkImg from './assets/action-prompt-example-dark.png'
+import actionPromptExampleImg from './assets/action-prompt-example.png'
+import actionPromptImg from './assets/action-prompt.png'
+import generatedActionCodeDarkImg from './assets/generated-action-code-dark.png'
+import generatedActionCodeImg from './assets/generated-action-code.png'
+import generatedActionDarkImg from './assets/generated-action-dark.png'
+import generatedActionImg from './assets/generated-action.png'
+import manualInputsDarkImg from './assets/manual-inputs-dark.png'
+import manualInputsImg from './assets/manual-inputs.png'
+
+import Tab from '@/components/tabs/Tab.astro'
+import Tabs from '@/components/tabs/Tabs.astro'
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+
Actions are **custom AI-generated tools** you can provide to your bot.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can use Actions to extend your bot's general functionality beyond what's available with the default [Cards](/studio/concepts/cards/introduction) or [integrations](/integrations/get-started/introduction). For example:
+
+- Make repeated API calls to an external service
+- Perform a specific calculation multiple times
+- Manipulate data and [variables](/studio/concepts/variables/overview)
+
+
+ Actions are code-based, but you don't need to write the code yourself—AI does all the work based on your prompt.
+
+
+---
+
+## Overview
+
+Actions are [TypeScript functions](https://www.typescriptlang.org/docs/handbook/2/functions.html) that execute their code whenever an [Autonomous Node](/studio/concepts/nodes/autonomous-node) calls them.
+
+Just like [Execute Code Cards](/studio/concepts/cards/execute-code), Actions let your bot use custom code. However, they're different in two important ways:
+
+- Actions are _only available in Autonomous Nodes_—they execute when AI decides they should
+- Actions are _re-usable_—your Autonomous Node can call them as many times as it needs
+
+---
+
+## Create an Action
+
+To create a new Action:
+
+1. Go to the **
Actions** menu in the Studio.
+2. Select **Create Action**.
+
+This opens the editor for your new Action. From here, you have two options:
+
+### Generate using AI (recommended)
+
+You can generate the entire Action using AI. In the bottom-left corner, write a prompt that describes what you want your Action to do:
+
+
+
+
+
+
+Your bot will generate code based on your prompt:
+
+
+
+
+
+
+If you want to refine the code, you can keep prompting to make updates.
+
+When you're happy with the generated code, select **Accept** to add it to your Action.
+
+### Write code yourself
+
+If you prefer, you can write the Action's code yourself—just edit the function on the right side of the editor.
+
+
+ For more information, check out our guide on [using code in Botpress Studio](/studio/guides/advanced/use-code).
+
+
+### Edit your Action's name/description
+
+Whether you generate your Action with AI or write it by hand, you can edit its name and description. Just select them in the upper-left corner of the editor, then enter a new name/description.
+
+---
+
+## Use Actions
+
+When you're ready to use an Action, you can add it to any Autonomous Node:
+
+1. Select **+ Add Card** on any Node to open the Card tray.
+2. Search for your Action, or find it under **Bot Actions**.
+3. Add it to the Autonomous Node.
+
+This gives your Autonomous Node access to execute the Action whenever it decides it's appropriate.
+
+### Give your Autonomous Node instructions
+
+If you add an Action to your Autonomous Node, you should add instructions to the Node's prompt so it knows when to use the Action. For example:
+
+```text
+Use the `fetchApiData` Action when you need data from an external API.
+```
+
+For more information, check out our guide on prompting your [Autonomous Node](/studio/concepts/nodes/autonomous-node#prompting-tips).
+
+### Manually provide inputs
+
+By default, the Autonomous Node decides how to fill in the Action's input fields based on the conversation's context. However, you can manually fill in these fields if you'd prefer:
+
+1. Select your Action from the Autonomous Node to open its inspector.
+2. Select the input field you want to manually fill in, then select **
Manual.**
+
+Now, you can manually fill in the field. For example, with data stored in a variable:
+
+
+
+
+
+
+---
+
+## Schemas
+
+Actions use input and output [Schemas](/studio/concepts/schemas) to tell your bot what data they expect and what data to return.
+
+Schemas are automatically created when you create an Action, and they automatically update when you edit your Action using AI. This means you don't have to worry about them if you're only using AI to generate your Action.
+
+### Use custom Schemas
+
+If you're writing any of your Action's code by hand, you can write or select a custom Schema:
+
+1. In your Action's editor, select **
Input Schema** or **
Output Schema**.
+2. Here, you can edit your Action's default Schema directly, or select a previously-created Schema from the drop-down menu.
diff --git a/src/content/docs/studio/concepts/agents/analytics-agent.mdx b/src/content/docs/studio/concepts/agents/analytics-agent.mdx
new file mode 100644
index 0000000..48b42cb
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/analytics-agent.mdx
@@ -0,0 +1,35 @@
+---
+title: Analytics Agent
+description: Collects, analyzes, and stores data on bot interactions.
+---
+
+import { Note, Warning } from '@/components/callouts'
+
+The Analytics Agent collects and analyzes data on bot interactions to provide insights into user behaviour, bot performance, and conversation trends. This agent is crucial for monitoring and improving the bot’s effectiveness.
+
+## Configuration
+
+
+Note
+
+The Analytics Agent is only available to Team and Enterprise subscribers.
+
+
+
+Once you've enabled the Analytics Agent from your bot's Agents menu, you can designate custom events that your bot will track. These events can be selected from the list of trackable events, or "Event Types."
+
+### Tracking custom events
+
+Follow these steps to track custom events:
+
+1. Place the "Track Event" card found in the "Agents" section of the card tray into a node
+2. In the details panel, use a descriptive name for the event that will allow you to keep track of it later. For example, you might track "Successful resolution" or "Unanswered question."
+
+Once you've successfully created a custom event, your bot will track each event as the card is executed in a given node. For example, your bot can track how many times a conversation successfully reaches a specific node, or how often users go through a certain node.
+
+
+Warning
+
+After creating a custom event, it can take up to an hour before the data is available to be visualized in your Analytics tab.
+
+
diff --git a/src/content/docs/studio/concepts/agents/hitl-agent.mdx b/src/content/docs/studio/concepts/agents/hitl-agent.mdx
new file mode 100644
index 0000000..fda5ab5
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/hitl-agent.mdx
@@ -0,0 +1,70 @@
+---
+title: HITL Agent
+description: Allows human intervention in the bot's conversations and decision-making.
+---
+
+import { Warning } from '@/components/callouts'
+
+
+ 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.
+
+
+
+The HITL (Human-in-the-Loop) Agent allows human intervention in the bot’s conversations and decision-making. This is particularly useful in complex scenarios where the bot might need confirmation or input from a human operator.
+
+## Configuration
+
+### Escalation Integration
+
+This is the integration you will use to handle the escalation.
+
+You can enable HITL with a prebuilt integration, or build a custom integration if you're using a third-party customer support provider that isn't listed here:
+
+| Integrations that support HITL |
+| :----------------------------- |
+| Zendesk |
+| HITL (Botpress) |
+
+### Queue Timeout
+
+This is the maximum wait time the bot will wait for an agent to handle the user's query. This time is set in minutes. If this timeout limit is reached, the bot will continue on with the current Workflow.
+
+### Intent to cancel HITL
+
+This option allows the user to cancel their request to speak to a human agent.
+
+The intents can be created and configured through the Library in the Studio.
+
+### Transcript Context
+
+This is what the bot will send to the human agent as additional context for the user's request. The default information includes the channel and integration on which the user was having the conversation, as well as both the Summary and Transcript variables generated by the Summary Agent.
+
+You can customize this to include whatever pieces of information are necessary for your specific scenario. This field supports variable expressions.
+
+### HITL Messages
+
+In these sections, you can customize what message your bot sends in various steps of the HITL process. These include:
+
+- while the end user is waiting to speak to an agent
+- when an agent is assigned to an end user
+- when the human agent ends the interaction
+- when the end user cancels the request
+- when the agent request times out
+
+## Exposed Variables
+
+The HITL Agent exposes three variables for use:
+
+```
+{{conversation.HITLAgent.isHitl}}
+```
+
+```
+{{conversation.HITLAgent.hitlSessionStatus}}
+```
+
+```
+{{conversation.HITLAgent.hitlContext}}
+```
diff --git a/src/content/docs/studio/concepts/agents/introduction.mdx b/src/content/docs/studio/concepts/agents/introduction.mdx
new file mode 100644
index 0000000..78c6fff
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/introduction.mdx
@@ -0,0 +1,61 @@
+---
+title: Agents
+description: Specialized components that extend the capabilities of a bot.
+sidebarTitle: Introduction
+---
+
+import CardGroup from '@/components/CardGroup.astro'
+import Card from '@/components/Card.astro'
+import Icon from '@/components/Icon.astro'
+
+
Agents **extend your bot's capabilities** beyond its basic functions. They perform tasks that
+enhance your bot's interactions with users, like:
+
+- [Enforcing policies](/studio/concepts/agents/policy-agent) across your bot's interactions
+- Allowing your bot to [communicate in multiple languages](/studio/concepts/agents/translator-agent)
+- Providing [summaries and transcripts](/studio/concepts/agents/summary-agent) of your bot's conversations
+
+## Guides
+
+Select any Agent to learn more about it:
+
+
+
+ Condenses the conversation into an AI-generated summary and transcript
+
+
+ Provides your bot with a personality or tone
+
+
+ Enforces business rules and compliance guidelines across your bot's interactions
+
+
+ Allows your bot to communicate in multiple languages
+
+
+ Retrieves information from the bot's knowledge base
+
+
+ Collects, analyzes, and stores data on bot interactions
+
+
+ Adds image recognition and visual processing capabilities to your bot
+
+
+ Allows human intervention in the bot's conversations and decision-making
+
+
+
+## Order of execution
+
+When your bot has multiple Agents enabled, they execute in the following order:
+
+1. Summary
+2. Personality
+3. Policy
+4. Translator
+5. Knowledge
+6. Vision
+7. Router
+8. Analytics
+9. HITL Agent
diff --git a/src/content/docs/studio/concepts/agents/knowledge-agent.mdx b/src/content/docs/studio/concepts/agents/knowledge-agent.mdx
new file mode 100644
index 0000000..4a86d87
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/knowledge-agent.mdx
@@ -0,0 +1,46 @@
+---
+title: Knowledge Agent
+description: Retrieves information from the bot's knowledge base.
+---
+
+The Knowledge Agent is responsible for retrieving information from the bot’s knowledge bases, such as FAQs, documents, websites, or structured databases. This agent is essential for providing accurate and detailed answers to user queries.
+
+## Configuration
+
+### Answer Manually
+
+When this option is enabled, your bot won't automatically provide answers in the conversation. The answers it generates will be saved to a dedicated variable which you can use manually in the conversation at a later point.
+
+### Additional Context
+
+This setting enables the bot to include extra contextual information when generating answers. By considering additional context, the Knowledge Agent can provide more accurate and relevant responses, especially in complex or nuanced scenarios.
+
+### Model Strategy
+
+The "Model Strategy" option allows you to choose how the Knowledge Agent selects and applies machine learning models to generate answers. Depending on your strategy, the agent can prioritize different models based on speed, accuracy, or specific use cases.
+
+**Fastest Model**: This is the model you designate as being the fastest, suited to your specific need. Generally, these are considered quicker, more performant, and less expensive models, and should be used when you anticipate simple queries.
+
+**Best Model**: This is the model you designate as being the most performant, suited to your specific need. Generally, this option should be used only when you anticipate that the additional performance of a more expensive model will be needed
+
+**Question Extractor Model**: This is the model used to extract questions from a conversation. Generally, you should follow the above rules here: a faster model if you anticipate simple queries, and a more performant one if the questions you expect to receive will be complex.
+
+### Chunks Count
+
+This is the number of chunks that Botpress will elect to send from the Knowledge Base to a model to generate an answer. A larger number of chunks will send more information to the model, generally resulting in more accurate answers, with longer generation times and a higher token cost.
+
+## Exposed Variables
+
+The Knowledge Agent exposes two variables that you can use:
+
+### Generated Response
+
+```
+{{turn.KnowledgeAgent.answer}}
+```
+
+### Response citations
+
+```
+{{turn.KnowledgeAgent.citations}}
+```
diff --git a/src/content/docs/studio/concepts/agents/personality-agent.mdx b/src/content/docs/studio/concepts/agents/personality-agent.mdx
new file mode 100644
index 0000000..9f5ec37
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/personality-agent.mdx
@@ -0,0 +1,22 @@
+---
+title: Personality Agent
+description: Provides your bot with a personality or tone.
+---
+
+The Personality Agent is used to provide the bot with a personality or tone. This agent controls how the bot expresses itself, including its language style, tone, and the types of responses it generates.
+
+## Configuration
+
+### Enable Personality Rewriting
+
+When this option is enabled, all of the messages your bot sends to end users will be rewritten to match the personality you indicate.
+
+### Personality Description
+
+The description you use here will be used along with an LLM to define and rewrite the messages your bot sends to end users. Think of this like the prompt you would send to an LLM to generate a certain type of response. You can include information about personality, tone, and purpose.
+
+This field also supports variable expressions. For example, you can use a predefined variable to dynamically change the name of the bot based on information you collect at the beginning of a conversation.
+
+### Model
+
+This is the model your bot will use to rewrite the responses it generates to suit the personality you've indicated in the Personality Description section.
diff --git a/src/content/docs/studio/concepts/agents/policy-agent.mdx b/src/content/docs/studio/concepts/agents/policy-agent.mdx
new file mode 100644
index 0000000..9eb438c
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/policy-agent.mdx
@@ -0,0 +1,32 @@
+---
+title: Policy Agent
+description: >-
+ Enforces business rules and compliance guidelines across your bot's
+ interactions.
+---
+
+The Policy Agent is designed to enforce business rules, compliance guidelines, or specific operational policies during bot interactions. It ensures that the bot adheres to legal, regulatory, or company-specific policies that you designate.
+
+## Configuration
+
+### Policy Description
+
+In this field, you can describe the policies to which you want your bot to adhere.
+
+If there are certain off-brand words that your bot should stay away from when generating responses, or you'd like your bot to avoid providing information about competitors' products or services, you can indicate that here.
+
+### Model
+
+This is the model used to influence and generate responses in accordance with the Policy Description.
+
+### Additional Information
+
+The Policy Agent is a powerful tool that enhances the safety and control of LLM-driven interactions by enforcing constraints and managing compliance across your bot's conversations. As organizations increasingly adopt AI-driven solutions, maintaining control over these systems is paramount. The Policy Agent acts as a safeguard, ensuring that all bot interactions remain within the defined boundaries of your business rules, regulatory standards, and operational policies. This not only helps protect your brand but also instills confidence in your organization's use of AI technology.
+
+One of the critical challenges with LLMs is the risk of generating responses that may be off-brand, inaccurate, or non-compliant—often referred to as "hallucinations." These hallucinations can lead to misleading or incorrect information being provided to users. The Policy Agent directly addresses this risk by functioning as a gatekeeper, filtering and controlling the responses generated by your AI. By configuring specific constraints, such as banned words, sensitive topics, or off-limits information, the Policy Agent ensures that the output remains aligned with your organization’s guidelines, protecting both your reputation and legal standing.
+
+The Policy Agent also introduces control mechanisms that act as gates for bot behaviour. These gates serve as checkpoints, ensuring that every interaction complies with designated business rules before it reaches the end user. This control extends to the specific contexts in which your AI operates, allowing it to adapt to various business needs while maintaining stringent adherence to predefined policies. Whether it's preventing the bot from discussing competitor products or controlling language to avoid sensitive terms, the Policy Agent’s gates provide a reliable framework to keep LLMs operating safely within set parameters.
+
+By integrating constraints directly into the model, the Policy Agent not only enhances compliance but also minimizes the likelihood of unwanted behaviours. These constraints act as a foundational control layer, enabling decision-makers to trust that Botpress bots will behave predictably and within the bounds of their company’s standards. The end result is a robust, reliable system that not only enhances the operational capabilities of your bots but also significantly reduces the risk of regulatory non-compliance and brand-damaging missteps.
+
+The Policy Agent provides a comprehensive solution for controlling LLM-driven interactions, ensuring that your organization’s use of AI remains safe, compliant, and within the bounds of designated rules. By implementing constraints, gates, and robust control measures, it acts as a critical safeguard, making it an essential tool for any business aiming to leverage AI while maintaining strict adherence to its policies.
diff --git a/src/content/docs/studio/concepts/agents/summary-agent.mdx b/src/content/docs/studio/concepts/agents/summary-agent.mdx
new file mode 100644
index 0000000..8ec3408
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/summary-agent.mdx
@@ -0,0 +1,40 @@
+---
+title: Summary Agent
+description: Condenses the conversation into an AI-generated summary and transcript.
+---
+
+The Summary Agent condenses lengthy or complex pieces of information gathered throughout a conversation into shorter, digestible summaries. This is particularly useful in scenarios where you need a quick understanding of a conversation or interaction's context without going through all the details.
+
+## Configuration
+
+### Summary Max Tokens
+
+This is the maximum length of the AI-generated summary, measured in tokens.
+
+### Transcript Max Lines
+
+This is the maximum length of the conversation transcript that the agent will record to the Conversation Transcript variable.
+
+### Model
+
+This is the model used to generate the summary that can be accessed through the Conversation Summary variable.
+
+## Exposed Variables
+
+The Summary Agent exposes two variables:
+
+### Conversation Summary
+
+```
+{{conversation.SummaryAgent.summary}}
+```
+
+The Conversation Summary variable stores an AI-generated summary of the conversation up to the point at which it's accessed.
+
+### Conversation Transcript
+
+```
+{{conversation.SummaryAgent.transcript}}
+```
+
+The Conversation Transcript variable stores an exact transcript of the conversation up to the point at which it's accessed.
diff --git a/src/content/docs/studio/concepts/agents/translator-agent.mdx b/src/content/docs/studio/concepts/agents/translator-agent.mdx
new file mode 100644
index 0000000..1bcdc28
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/translator-agent.mdx
@@ -0,0 +1,32 @@
+---
+title: Translator Agent
+description: Enables your bot to communicate in multiple languages.
+---
+
+The Translator Agent enables the bot to communicate in multiple languages by automatically translating text between different languages. This agent is crucial for bots that need to operate in a multilingual environment.
+
+## Configuration
+
+### Detect Initial User Language
+
+When this option is enabled, the agent will automatically detect the language in which the user is communicating on the first incoming message it receives.
+
+The message must be at least 3 tokens in order to be processed by the agent. Note that this process will automatically overwrite the language variable, even if you set that variable manually at the beginning of the conversation.
+
+### Detect Language Change
+
+When this option is enabled, the agent will attempt to detect the user's language on ever conversation turn. This is particularly useful if you expect the user's language to switch throughout a single conversation.
+
+If this option is disabled, the agent will only detect the user's language when it's designated as 'null'.
+
+### Model
+
+This is the model your agent will use to translate messages.
+
+## Exposed Variables
+
+The Translator Agent exposes one variable for use:
+
+```
+{{user.TranslatorAgent.language}}
+```
diff --git a/src/content/docs/studio/concepts/agents/vision-agent.mdx b/src/content/docs/studio/concepts/agents/vision-agent.mdx
new file mode 100644
index 0000000..d272c37
--- /dev/null
+++ b/src/content/docs/studio/concepts/agents/vision-agent.mdx
@@ -0,0 +1,30 @@
+---
+title: Vision Agent
+description: Adds image recognition and visual processing capabilities to your bot.
+---
+
+import { Info } from '@/components/callouts'
+
+The Vision Agent adds image recognition and visual processing capabilities to the bot. It allows the bot to analyze and interpret visual data, such as images, screenshots, or camera feeds.
+
+
+ To use the Vision Agent, you need to: - Add the **Extract Content from Image** Card to your Autonomous Node - Enable
+ **Extract from Incoming Images** in your [Autonomous Node's
+ configuration](/studio/concepts/nodes/autonomous-node#configuration)
+
+
+## Configuration
+
+### Extract from Incoming Images
+
+When this option is enabled, the bot will attempt to extract any text content from an image. It will also produce a description of the image itself.
+
+The Vision Agent will save any extracted content and descriptions to the variable it exposes.
+
+### Exposed Variables
+
+The Vision Agent exposes one variable for use:
+
+```
+{{turn.Visionagent.content}}
+```
diff --git a/src/content/docs/studio/concepts/assets/action-prompt-dark.png b/src/content/docs/studio/concepts/assets/action-prompt-dark.png
new file mode 100644
index 0000000..1faca1e
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/action-prompt-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/action-prompt-example-dark.png b/src/content/docs/studio/concepts/assets/action-prompt-example-dark.png
new file mode 100644
index 0000000..749bfdc
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/action-prompt-example-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/action-prompt-example.png b/src/content/docs/studio/concepts/assets/action-prompt-example.png
new file mode 100644
index 0000000..658b8e5
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/action-prompt-example.png differ
diff --git a/src/content/docs/studio/concepts/assets/action-prompt.png b/src/content/docs/studio/concepts/assets/action-prompt.png
new file mode 100644
index 0000000..a7be91e
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/action-prompt.png differ
diff --git a/src/content/docs/studio/concepts/assets/add-trigger.png b/src/content/docs/studio/concepts/assets/add-trigger.png
new file mode 100644
index 0000000..04c1c72
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/add-trigger.png differ
diff --git a/src/content/docs/studio/concepts/assets/auto-compute.png b/src/content/docs/studio/concepts/assets/auto-compute.png
new file mode 100644
index 0000000..199c86f
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/auto-compute.png differ
diff --git a/src/content/docs/studio/concepts/assets/botpress-hub.png b/src/content/docs/studio/concepts/assets/botpress-hub.png
new file mode 100644
index 0000000..99775a8
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/botpress-hub.png differ
diff --git a/src/content/docs/studio/concepts/assets/code-editor.png b/src/content/docs/studio/concepts/assets/code-editor.png
new file mode 100644
index 0000000..7c3a875
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/code-editor.png differ
diff --git a/src/content/docs/studio/concepts/assets/comm-channels-dark.png b/src/content/docs/studio/concepts/assets/comm-channels-dark.png
new file mode 100644
index 0000000..cf4e09d
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/comm-channels-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/comm-channels.png b/src/content/docs/studio/concepts/assets/comm-channels.png
new file mode 100644
index 0000000..16b739e
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/comm-channels.png differ
diff --git a/src/content/docs/studio/concepts/assets/computed-column-switch.png b/src/content/docs/studio/concepts/assets/computed-column-switch.png
new file mode 100644
index 0000000..e47b14c
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/computed-column-switch.png differ
diff --git a/src/content/docs/studio/concepts/assets/conversation-started.png b/src/content/docs/studio/concepts/assets/conversation-started.png
new file mode 100644
index 0000000..98c6d77
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/conversation-started.png differ
diff --git a/src/content/docs/studio/concepts/assets/copy-to-bot.png b/src/content/docs/studio/concepts/assets/copy-to-bot.png
new file mode 100644
index 0000000..80beaf4
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/copy-to-bot.png differ
diff --git a/src/content/docs/studio/concepts/assets/custom-trigger-buttons.png b/src/content/docs/studio/concepts/assets/custom-trigger-buttons.png
new file mode 100644
index 0000000..849b6ee
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/custom-trigger-buttons.png differ
diff --git a/src/content/docs/studio/concepts/assets/default-workflows-dark.png b/src/content/docs/studio/concepts/assets/default-workflows-dark.png
new file mode 100644
index 0000000..2b7d420
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/default-workflows-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/default-workflows.png b/src/content/docs/studio/concepts/assets/default-workflows.png
new file mode 100644
index 0000000..2e9187b
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/default-workflows.png differ
diff --git a/src/content/docs/studio/concepts/assets/edit-code-button.png b/src/content/docs/studio/concepts/assets/edit-code-button.png
new file mode 100644
index 0000000..4205f76
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/edit-code-button.png differ
diff --git a/src/content/docs/studio/concepts/assets/end-workflow-dark.png b/src/content/docs/studio/concepts/assets/end-workflow-dark.png
new file mode 100644
index 0000000..4d56296
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/end-workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/end-workflow.png b/src/content/docs/studio/concepts/assets/end-workflow.png
new file mode 100644
index 0000000..bf58a48
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/end-workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/error-workflow-dark.png b/src/content/docs/studio/concepts/assets/error-workflow-dark.png
new file mode 100644
index 0000000..603f660
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/error-workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/error-workflow.png b/src/content/docs/studio/concepts/assets/error-workflow.png
new file mode 100644
index 0000000..852655d
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/error-workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/event-debugger-logs-json.png b/src/content/docs/studio/concepts/assets/event-debugger-logs-json.png
new file mode 100644
index 0000000..31e6d80
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/event-debugger-logs-json.png differ
diff --git a/src/content/docs/studio/concepts/assets/fire-trigger.png b/src/content/docs/studio/concepts/assets/fire-trigger.png
new file mode 100644
index 0000000..a4709d3
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/fire-trigger.png differ
diff --git a/src/content/docs/studio/concepts/assets/flow-logic-dark.png b/src/content/docs/studio/concepts/assets/flow-logic-dark.png
new file mode 100644
index 0000000..cf414af
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/flow-logic-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/flow-logic.png b/src/content/docs/studio/concepts/assets/flow-logic.png
new file mode 100644
index 0000000..d484558
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/flow-logic.png differ
diff --git a/src/content/docs/studio/concepts/assets/generated-action-code-dark.png b/src/content/docs/studio/concepts/assets/generated-action-code-dark.png
new file mode 100644
index 0000000..58e9f6a
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/generated-action-code-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/generated-action-code.png b/src/content/docs/studio/concepts/assets/generated-action-code.png
new file mode 100644
index 0000000..7b8a94f
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/generated-action-code.png differ
diff --git a/src/content/docs/studio/concepts/assets/generated-action-dark.png b/src/content/docs/studio/concepts/assets/generated-action-dark.png
new file mode 100644
index 0000000..cb32a0f
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/generated-action-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/generated-action.png b/src/content/docs/studio/concepts/assets/generated-action.png
new file mode 100644
index 0000000..38726be
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/generated-action.png differ
diff --git a/src/content/docs/studio/concepts/assets/home-instructions-dark.png b/src/content/docs/studio/concepts/assets/home-instructions-dark.png
new file mode 100644
index 0000000..d18fabd
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/home-instructions-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/home-instructions.png b/src/content/docs/studio/concepts/assets/home-instructions.png
new file mode 100644
index 0000000..dccdd09
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/home-instructions.png differ
diff --git a/src/content/docs/studio/concepts/assets/input-type-text-advance.png b/src/content/docs/studio/concepts/assets/input-type-text-advance.png
new file mode 100644
index 0000000..39b8731
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/input-type-text-advance.png differ
diff --git a/src/content/docs/studio/concepts/assets/input-type-text.png b/src/content/docs/studio/concepts/assets/input-type-text.png
new file mode 100644
index 0000000..8c888fd
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/input-type-text.png differ
diff --git a/src/content/docs/studio/concepts/assets/knowledge-base-dark.png b/src/content/docs/studio/concepts/assets/knowledge-base-dark.png
new file mode 100644
index 0000000..0acaaf0
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/knowledge-base-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/knowledge-base.png b/src/content/docs/studio/concepts/assets/knowledge-base.png
new file mode 100644
index 0000000..0fe6b64
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/knowledge-base.png differ
diff --git a/src/content/docs/studio/concepts/assets/learning-experiences-dark.png b/src/content/docs/studio/concepts/assets/learning-experiences-dark.png
new file mode 100644
index 0000000..be9ae0e
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/learning-experiences-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/learning-experiences.png b/src/content/docs/studio/concepts/assets/learning-experiences.png
new file mode 100644
index 0000000..7c40451
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/learning-experiences.png differ
diff --git a/src/content/docs/studio/concepts/assets/main-workflow-dark.png b/src/content/docs/studio/concepts/assets/main-workflow-dark.png
new file mode 100644
index 0000000..0b06475
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/main-workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/main-workflow.png b/src/content/docs/studio/concepts/assets/main-workflow.png
new file mode 100644
index 0000000..100fb2a
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/main-workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/manual-inputs-dark.png b/src/content/docs/studio/concepts/assets/manual-inputs-dark.png
new file mode 100644
index 0000000..ade3ebb
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/manual-inputs-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/manual-inputs.png b/src/content/docs/studio/concepts/assets/manual-inputs.png
new file mode 100644
index 0000000..c4b6051
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/manual-inputs.png differ
diff --git a/src/content/docs/studio/concepts/assets/new-workflow-dark.png b/src/content/docs/studio/concepts/assets/new-workflow-dark.png
new file mode 100644
index 0000000..dafb3e5
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/new-workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/new-workflow.png b/src/content/docs/studio/concepts/assets/new-workflow.png
new file mode 100644
index 0000000..2ab5237
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/new-workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/node-cards-dark.png b/src/content/docs/studio/concepts/assets/node-cards-dark.png
new file mode 100644
index 0000000..296e9d3
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/node-cards-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/node-cards.png b/src/content/docs/studio/concepts/assets/node-cards.png
new file mode 100644
index 0000000..7ba87d0
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/node-cards.png differ
diff --git a/src/content/docs/studio/concepts/assets/node-instructions-dark.png b/src/content/docs/studio/concepts/assets/node-instructions-dark.png
new file mode 100644
index 0000000..049865b
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/node-instructions-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/node-instructions.png b/src/content/docs/studio/concepts/assets/node-instructions.png
new file mode 100644
index 0000000..9feee66
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/node-instructions.png differ
diff --git a/src/content/docs/studio/concepts/assets/stale-compute-row.png b/src/content/docs/studio/concepts/assets/stale-compute-row.png
new file mode 100644
index 0000000..d3190df
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/stale-compute-row.png differ
diff --git a/src/content/docs/studio/concepts/assets/table-code-operations.png b/src/content/docs/studio/concepts/assets/table-code-operations.png
new file mode 100644
index 0000000..8c28114
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/table-code-operations.png differ
diff --git a/src/content/docs/studio/concepts/assets/table-dependencies.png b/src/content/docs/studio/concepts/assets/table-dependencies.png
new file mode 100644
index 0000000..79b873c
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/table-dependencies.png differ
diff --git a/src/content/docs/studio/concepts/assets/test-events.png b/src/content/docs/studio/concepts/assets/test-events.png
new file mode 100644
index 0000000..caa6b51
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/test-events.png differ
diff --git a/src/content/docs/studio/concepts/assets/test-trigger.png b/src/content/docs/studio/concepts/assets/test-trigger.png
new file mode 100644
index 0000000..27d8002
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/test-trigger.png differ
diff --git a/src/content/docs/studio/concepts/assets/timeout-workflow-dark.png b/src/content/docs/studio/concepts/assets/timeout-workflow-dark.png
new file mode 100644
index 0000000..bfcfa3d
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/timeout-workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/timeout-workflow.png b/src/content/docs/studio/concepts/assets/timeout-workflow.png
new file mode 100644
index 0000000..4b9c966
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/timeout-workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/tools-dark.png b/src/content/docs/studio/concepts/assets/tools-dark.png
new file mode 100644
index 0000000..8e924ff
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/tools-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/tools.png b/src/content/docs/studio/concepts/assets/tools.png
new file mode 100644
index 0000000..2e5f128
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/tools.png differ
diff --git a/src/content/docs/studio/concepts/assets/transition-card-dark.png b/src/content/docs/studio/concepts/assets/transition-card-dark.png
new file mode 100644
index 0000000..7b09835
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/transition-card-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/transition-card.png b/src/content/docs/studio/concepts/assets/transition-card.png
new file mode 100644
index 0000000..8d62d07
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/transition-card.png differ
diff --git a/src/content/docs/studio/concepts/assets/trigger-emulator.png b/src/content/docs/studio/concepts/assets/trigger-emulator.png
new file mode 100644
index 0000000..cfeead1
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/trigger-emulator.png differ
diff --git a/src/content/docs/studio/concepts/assets/trigger.png b/src/content/docs/studio/concepts/assets/trigger.png
new file mode 100644
index 0000000..dd98e73
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/trigger.png differ
diff --git a/src/content/docs/studio/concepts/assets/welcome-message.png b/src/content/docs/studio/concepts/assets/welcome-message.png
new file mode 100644
index 0000000..f6a42ec
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/welcome-message.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflow-dark.png b/src/content/docs/studio/concepts/assets/workflow-dark.png
new file mode 100644
index 0000000..84b74d2
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflow-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflow-folders-dark.png b/src/content/docs/studio/concepts/assets/workflow-folders-dark.png
new file mode 100644
index 0000000..e02f458
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflow-folders-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflow-folders.png b/src/content/docs/studio/concepts/assets/workflow-folders.png
new file mode 100644
index 0000000..a422f52
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflow-folders.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflow.png b/src/content/docs/studio/concepts/assets/workflow.png
new file mode 100644
index 0000000..23d5a07
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflow.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflows-hub-dark.png b/src/content/docs/studio/concepts/assets/workflows-hub-dark.png
new file mode 100644
index 0000000..02dd592
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflows-hub-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflows-hub.png b/src/content/docs/studio/concepts/assets/workflows-hub.png
new file mode 100644
index 0000000..7b58a5c
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflows-hub.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflows-menu-dark.png b/src/content/docs/studio/concepts/assets/workflows-menu-dark.png
new file mode 100644
index 0000000..ec30f82
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflows-menu-dark.png differ
diff --git a/src/content/docs/studio/concepts/assets/workflows-menu.png b/src/content/docs/studio/concepts/assets/workflows-menu.png
new file mode 100644
index 0000000..fc4c093
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/workflows-menu.png differ
diff --git a/src/content/docs/studio/concepts/assets/zendesk-triggers.png b/src/content/docs/studio/concepts/assets/zendesk-triggers.png
new file mode 100644
index 0000000..6edf9cb
Binary files /dev/null and b/src/content/docs/studio/concepts/assets/zendesk-triggers.png differ
diff --git a/src/content/docs/studio/concepts/bot-settings.mdx b/src/content/docs/studio/concepts/bot-settings.mdx
new file mode 100644
index 0000000..ed4c595
--- /dev/null
+++ b/src/content/docs/studio/concepts/bot-settings.mdx
@@ -0,0 +1,77 @@
+---
+title: Bot Settings
+icon: Settings
+---
+
+import { Tip, Warning } from '@/components/callouts'
+import Icon from '@/components/Icon.astro'
+
+The **
Bot Settings** menu lets you adjust general settings that apply to your bot.
+
+## General options
+
+### Bot name
+
+Use this field to set a name for your bot. This name will display to users, regardless of which channel your bot is deployed on.
+
+## Workflow options
+
+### Inactivity timeout
+
+This is the amount of time, in minutes, that your bot will wait for a response before ending the session. When the session ends, your bot will automatically trigger the [Timeout Workflow](/studio/concepts/workflows#timeout). This clears the user's position in the Workflow and resets any Workflow variables.
+
+You can set this to 0 to prevent the bot from ever timing out. The maximum value is 1440 minutes, or 24 hours.
+
+### Node repetition limit
+
+This is the maximum amount of times a conversation can go through any specific Node. When the user reaches this node repetition limit, an error will be triggered.
+
+The maximum value is 10.
+
+### Use the Botpress Client
+
+This option lets you access the [official Botpress client for TypeScript](https://www.npmjs.com/package/@botpress/client) within Studio.
+
+When enabled, the `client` object is imported by default anywhere you can [use code in Studio](/studio/guides/advanced/use-code).
+
+### Configuration variables
+
+Here, you can [define and manage configuration variables](/studio/concepts/variables/scopes/configuration) for your bot.
+
+## LLM options
+
+In this section, you can configure which Large Language Model (LLM) your bot's [Autonomous Nodes](/studio/concepts/nodes/autonomous-node) should use depending on its current task.
+
+
+ You can [override these settings](/studio/concepts/nodes/autonomous-node#override-default-models) for individual
+ Autonomous Nodes.
+
+
+### Default fast LLM
+
+This is the model your bot will use for quick and easy tasks, prioritizing speed and cost over performance.
+
+### Default best LLM
+
+This is the model your bot will use for complex tasks that need the highest-quality responses.
+
+### Autonomous language model
+
+This is the model that powers your bot's inference engine and generates responses.
+
+### RAG language model
+
+This is the model your bot will use for Retrieval-Augmented Generation (RAG) tasks, like answering questions based on [Knowledge Base](/studio/concepts/knowledge-base/introduction) content.
+
+### Fallback LLM
+
+This is the model your bot will use when one of your preferred models is unavailable.
+
+### LLMz version
+
+This option lets you configure which version of Botpress' custom inference engine, LLMz, your bot uses.
+
+
+ We recommend always using latest stable version of LLMz. However, you may find that a bot built on previous versions
+ of LLMz works best on those versions.
+
diff --git a/src/content/docs/studio/concepts/botpress-hub.mdx b/src/content/docs/studio/concepts/botpress-hub.mdx
new file mode 100644
index 0000000..20d88d9
--- /dev/null
+++ b/src/content/docs/studio/concepts/botpress-hub.mdx
@@ -0,0 +1,10 @@
+---
+title: Botpress Hub
+---
+
+import { Picture } from 'astro:assets'
+import botpressHubImg from './assets/botpress-hub.png'
+
+
+
+[Botpress Hub](https://botpress.com/hub) is a marketplace for pre-built integrations and skills. It's a great way to get started with Botpress and to extend your bot's capabilities.
diff --git a/src/content/docs/studio/concepts/card-hub.mdx b/src/content/docs/studio/concepts/card-hub.mdx
new file mode 100644
index 0000000..83028d1
--- /dev/null
+++ b/src/content/docs/studio/concepts/card-hub.mdx
@@ -0,0 +1,48 @@
+---
+title: Hub
+description: >-
+ Download and install integrations with external services or premade Workflows
+ from across the web.
+icon: Boxes
+---
+
+import Tooltip from '@/components/Tooltip.astro'
+
+From the Hub, you can download and install prebuilt Workflows or integrations for use within your bots. The Hub is designed to save time and enhance your development by providing access to Workflows and integrations created by Botpress, your team, or other
bot builders in the community.
+
+Cards and integrations are accessible through the Hub, a centralized library where you can browse and select assets to add directly to your projects. Whether you're integrating common functions like user authentication, setting up a third-party service like a CRM or analytics provider, or implementing complex interactions like a multi-step booking Workflow, the Hub makes it easy to find and deploy what you need.
+
+## Accessing the Hub
+
+The Hub is accessible from the top of the Studio, represented by an icon shaped like a globe.
+
+## Installation and use
+
+Use the search bar to look for specific functions, like 'message delay' or 'NPS survey,' or integrations with external services like 'HubSpot'.
+
+When you've found a Workflow or integration you want to install, click on the 'Install' button.
+
+- Workflows will be added for use to your card tray
+- Integrations will usually make a set of cards available in a dedicated section of your card tray.
+
+Both Workflows and integrations usually require some configuration before they can be used.
+
+You can use a card by dragging it from the tray into a node. When the Workflow reaches this card, your bot will execute the prebuilt Workflow, along with any options you were prompted to configure during installation.
+
+For integrations, follow the prompts to configure the service as needed.
+
+## Customizing a Workflow
+
+Right-clicking on a Workflow card once you've added it to your Workflow, or revisiting the installation menu from the Hub, allows you to make a copy of the Card and modify its contents.
+
+This creates a version of the installed Card available as a Workflow directly in your bot, enabling you to make any custom changes needed.
+
+These changes won't affect the public listing of the Workflow.
+
+## Sharing Workflows
+
+To share your own Workflow as a card available on the Hub, follow these steps:
+
+1. Navigate to the Workflow you'd like to share.
+2. On the right-side panel, click 'Share Workflow.'
+3. Follow the steps in this menu to make the Card public.
diff --git a/src/content/docs/studio/concepts/cards/agents.mdx b/src/content/docs/studio/concepts/cards/agents.mdx
new file mode 100644
index 0000000..18fa90c
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/agents.mdx
@@ -0,0 +1,22 @@
+---
+title: Agents
+description: Cards that interact with specific Agent functionalities.
+---
+
+The cards in the Agents category allow you to perform actions that integrate with your agent's functionalities in some way.
+
+## Knowledge Agent
+
+The Query Knowledge Bases card allows you to programmatically query Knowledge Bases from within your bot. This card is useful when you want to retrieve information from your Knowledge Bases and display it to the user during the conversation.
+
+This supports variables and expressions. and won't send the answer directly to the user.
+
+### Query
+
+The question you want to ask to the Knowledge Base. You can type the question directly or use variables. for example: `{{event.preview}}` or `{{workflow.question}}`
+
+### Included Knowledge Bases
+
+Select in which Knowledge Bases to answer questions from. By default, it uses all the Knowledge Bases.
+
+The result will be stored in `{{turn.KnowledgeAgent.answer}}` and `{{turn.KnowledgeAgent.citations}}`. You can also store the answer in Workflow variables.
diff --git a/src/content/docs/studio/concepts/cards/ai/ai-generate-text.mdx b/src/content/docs/studio/concepts/cards/ai/ai-generate-text.mdx
new file mode 100644
index 0000000..ec7cfcc
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/ai/ai-generate-text.mdx
@@ -0,0 +1,31 @@
+---
+title: AI Generate Text
+description: A card that allows you to define a custom prompt to generate text.
+---
+
+import { Note } from '@/components/callouts'
+
+The AI Generate Text card is a specific type of AI Task that helps you generate text based on a prompt and a few settings. This is useful for countless different use cases such as:
+
+- Generating catchy blog titles from a topic or keyword
+- Summarizing long texts or documents in a few sentences
+- Creating articles from bullet points or outlines
+- Writing product descriptions that highlight the features and benefits
+- Crafting creative content such as stories, poems, lyrics, and more!
+
+## Using AI Generate Text
+
+You have a few settings in the AI Generate Text card:
+
+- Prompt: the text you want to use as a starting point for the AI to generate content, you can use variables here (like `{{event.preview}}` to get the last user message)
+- Output variable: the variable where the generated text will be stored
+- Advanced settings > Model: the LLM model you want to use to generate the text (the current options are GPT-3 and GPT-4)
+- Advanced settings > Temperature: the higher the temperature, the more creative the text will be
+- Advanced settings > Output length: the length of the generated text in tokens. Check out [this article by OpenAI](https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them) to learn more about LLM tokens.
+
+
+Note
+
+Use variables in the prompt to make the generated text more dynamic. For example, `{{event.preview}}` to get the last user message or `{{conversation.SummaryAgent.transcript}}` to get the history of the conversation and use it as a starting point for the AI.
+
+
diff --git a/src/content/docs/studio/concepts/cards/ai/ai-task.mdx b/src/content/docs/studio/concepts/cards/ai/ai-task.mdx
new file mode 100644
index 0000000..f92acd3
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/ai/ai-task.mdx
@@ -0,0 +1,53 @@
+---
+title: AI Task
+description: Perform specific and defined AI-powered actions in your bot's Workflow.
+---
+
+## AI Task Overview
+
+The AI Task is a tool for generating content using AI and can be used to automate a wide range of tasks. By providing clear instructions, specific inputs, and well-named variables, users can leverage the full capabilities of this tool to improve their Workflows and boost their productivity.
+
+### Task Instructions
+
+To accomplish a generative task using the **AI Task Card**, users will need to provide specific instructions in natural language on what they want the AI engine to generate. This can be done using the **Task Instructions** parameter.
+
+Users should provide a clear and detailed description of the task they want the AI engine to perform, including any relevant constraints or guidelines that should be followed.
+
+There is a certain date beyond which the information isn't available to the AI model. You can find that date on the model you use (for example [GPT-3-5](https://platform.openai.com/docs/models/gpt-3-5) ). If you want to get around this, please use a Knowledge Base and add its answer as an input to give context to the AI Task.
+
+### AI Task Input
+
+This is the input that will be sent to the Generative AI Engine. Think of it as the problem subject. Users should be as specific as possible when providing the AI task input, as this will help the AI engine generate more accurate and relevant content. You can use multiple variants as an input - not limited to:
+
+To make your AI task take into account the current date, you need to include it in the input by using this code snippet that shows the current date in JavaScript format: `Today's date: {{ new Date().toLocaleString() }}`
+
+### Storing result in variables
+
+This allows users to specify the variables where the extracted information will be stored within Botpress. It's important to choose variable names that are easy to understand and identify, as these variables will be used to reference the generated content in other parts of the Studio and it will influence the AI task on what to extract and how.
+
+## Task Example
+
+### Example Input
+
+By providing clear and realistic examples, you can help the AI better understand its task and be used\\\
+to solve real-world problems and generate useful content. This can ultimately lead to a more successful and productive experience for users who are targeting the power of artificial intelligence in their Workflows.
+
+### Displaying result (optional)
+
+You still need a content-type card to display the output of the AI Task Card if you want to.
+
+## Advanced Settings
+
+### Temperature
+
+Temperature is a setting that controls how creative and varied the responses generated by an AI language model can be. Think of it like a dial that you can turn up or down to control how much the AI is allowed to come up with new and different responses. It ranges from 0 to 1.
+
+When the temperature is set to 0, the AI will stick to the same answer most of the time, which can be useful for tasks that require consistency and accuracy. However, if you want more creative and varied responses, you can turn up the temperature, and the AI will come up with more diverse answers that may not always be the same.
+
+For example, if you ask the LLM "What is your favorite animal?", with a temperature of 1 it might respond with "My favorite animal is a cat because they're cute and cuddly", but it might also generate a response like "My favorite animal is a platypus because they're such odd creatures and so unique". Both responses are consistent with the LLM's training data (which includes information about cats and platypuses), but the second response is more creative and unexpected.
+
+In simpler terms, temperature is a way to control how much "imagination" the AI has when generating responses. A lower temperature means more consistency, while a higher temperature means more creativity and variability.
+
+### Add transition to handle failure
+
+You can enable this option to have your bot transition to another node when an issue happens with the AI Task. The possible issues are: Request Timeout (when the AI can't answer in a timely manner), Token Overflow (when the input or the output of the task exceeds the limit) and others.
diff --git a/src/content/docs/studio/concepts/cards/ai/ai-transition.mdx b/src/content/docs/studio/concepts/cards/ai/ai-transition.mdx
new file mode 100644
index 0000000..3cdd3b5
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/ai/ai-transition.mdx
@@ -0,0 +1,27 @@
+---
+title: AI Transition
+description: >-
+ Transition card that uses AI to determine a user's intent from a natural
+ language input.
+---
+
+import { Info } from '@/components/callouts'
+
+## AI Transition Overview
+
+The AI Transition card is a specific type of AI Task that helps you classify text into a set of predefined categories. This is useful for several different cases such as assessing the user intent without needing to create training phrases, or extracting the main topic of a text.
+
+## Using AI Transitions
+
+You have three fields in the AI Transition card:
+
+- Text to categorize: the text input you want to process, you can use variables here (like `{{event.preview}}` to get the last user message)
+- Categories: the list of categories you want to use to classify the text.
+- Store result in variable (Optional): allows you to select a variable to store the resulting category in. This is useful if you want to use the category later in the conversation.
+
+
+Info
+
+You can use the AI Transition card to replace Intents. You just need to create a category for each intent you want to replace, and use the AI Transition card instead of adding multiple inline or Library intents.
+
+
diff --git a/src/content/docs/studio/concepts/cards/ai/introduction.mdx b/src/content/docs/studio/concepts/cards/ai/introduction.mdx
new file mode 100644
index 0000000..8891761
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/ai/introduction.mdx
@@ -0,0 +1,26 @@
+---
+title: AI
+description: These cards use AI by default to power their actions.
+sidebarTitle: Introduction
+---
+
+import { Tip } from '@/components/callouts'
+
+The cards in the AI section of the card tray are specialized tools that leverage advanced AI capabilities, including natural language processing, data analysis, and machine learning, to enhance your bot's functionality. These cards allow your bot to perform complex tasks, such as summarizing content, translating languages, analyzing user input, and more, adding intelligence and adaptability to your conversational Workflows.
+
+
+AI is everywhere!
+
+In addition to these dedicated, AI-powered cards, you'll find that LLMs power almost every aspect of the Botpress conversational experience.
+
+These cards provide you direct, task-based access to LLMs, giving you more control over their inputs and outputs.
+
+
+
+There are three types of cards made available to you in the AI section of the card tray:
+
+[AI Task](/studio/concepts/cards/ai/ai-task)
+
+[AI Transition](/studio/concepts/cards/ai/ai-transition)
+
+[AI Generate Text](/studio/concepts/cards/ai/ai-generate-text)
diff --git a/src/content/docs/studio/concepts/cards/assets/card-inspector-dark.png b/src/content/docs/studio/concepts/cards/assets/card-inspector-dark.png
new file mode 100644
index 0000000..c5b6d81
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/card-inspector-dark.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/card-inspector.png b/src/content/docs/studio/concepts/cards/assets/card-inspector.png
new file mode 100644
index 0000000..5041e2a
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/card-inspector.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/cards-dark.png b/src/content/docs/studio/concepts/cards/assets/cards-dark.png
new file mode 100644
index 0000000..8b8ae77
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/cards-dark.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/cards.png b/src/content/docs/studio/concepts/cards/assets/cards.png
new file mode 100644
index 0000000..5d4f3cd
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/cards.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/cron-settings.png b/src/content/docs/studio/concepts/cards/assets/cron-settings.png
new file mode 100644
index 0000000..81b748b
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/cron-settings.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/execute-code-dark.png b/src/content/docs/studio/concepts/cards/assets/execute-code-dark.png
new file mode 100644
index 0000000..fc40dc2
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/execute-code-dark.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/execute-code.png b/src/content/docs/studio/concepts/cards/assets/execute-code.png
new file mode 100644
index 0000000..382eadb
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/execute-code.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/fixed-schedule-options.png b/src/content/docs/studio/concepts/cards/assets/fixed-schedule-options.png
new file mode 100644
index 0000000..7d1f169
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/fixed-schedule-options.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/fixed-schedule.png b/src/content/docs/studio/concepts/cards/assets/fixed-schedule.png
new file mode 100644
index 0000000..63df894
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/fixed-schedule.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/invalid-cron.png b/src/content/docs/studio/concepts/cards/assets/invalid-cron.png
new file mode 100644
index 0000000..c170084
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/invalid-cron.png differ
diff --git a/src/content/docs/studio/concepts/cards/assets/trigger-menu.png b/src/content/docs/studio/concepts/cards/assets/trigger-menu.png
new file mode 100644
index 0000000..e21b2df
Binary files /dev/null and b/src/content/docs/studio/concepts/cards/assets/trigger-menu.png differ
diff --git a/src/content/docs/studio/concepts/cards/capture-information.mdx b/src/content/docs/studio/concepts/cards/capture-information.mdx
new file mode 100644
index 0000000..c8a4099
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/capture-information.mdx
@@ -0,0 +1,1487 @@
+---
+title: Capture Information
+description: >-
+ Cards that stop the bot's Workflow and waits for a user's response to capture
+ specific pieces of information.
+---
+
+import { Tip, Note, Warning } from '@/components/callouts'
+
+**Capture Information** cards instruct the bot to stop processing and wait for the user's response while capturing a specific piece of information from the user's input.
+
+This could include details like the user's name, full address, or raw input.
+
+To collect multiple pieces of information, multiple prompt fields can be added to a single prompt node. Once the information is collected, a Workflow variable should be created to store the extracted information for later use in the conversation or to be passed on to other systems. This allows for a more personalized and efficient experience for the user, as well as providing valuable data for the bot's developers.
+
+## Prompt Field Types
+
+A Prompt Field is a type of input field that's used to capture information from a user in a structured and organized manner. It can include various types of input fields such as Single Choice, Multiple Choice, Number, Email Address, Phone Number, and more.
+
+The Prompt Field also includes validation messages and code validation, which helps ensure that the user inputs the correct type of information. This means that if the user inputs an invalid value, they will be notified with an error message and prompted to re-enter the correct information.
+
+
+
+
+ |
+ **Prompt Fields**
+ |
+
+
+ **Description & Extracted Information**
+ |
+
+
+
+
+
+
+ |
+ [SingleChoice](#single-choice)
+ |
+
+
+ Extracts a Single Choice from a finite list of possible Values\
+ Variable Type: String
+ |
+
+
+
+ |
+ [MultipleChoice](#multi-choice)
+ |
+
+
+ Extracts one or multiple choices from a finite list of possible Values\
+ Variable Type: String
+ |
+
+
+
+ |
+ [Boolean](#boolean)
+ |
+
+
+ Extract a Boolean (On/Off) from the Query\
+ Variable Type: Boolean
+ |
+
+
+
+ |
+ [Confirmation](#confirmation)
+ |
+
+
+ Confirm a Yes/No question with a Boolean from the Query\
+ Variable Type: Boolean
+ |
+
+
+
+ |
+ [Number](#number)
+ |
+
+
+ Extracts a Number from the Query\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [EmailAddress](#email-address)
+ |
+
+
+ Extracts a full Email Address from the Query\
+ Variable Type: String
+ |
+
+
+
+ |
+ [PhoneNumber](#phone-number)
+ |
+
+
+ Extracts a Telephone Number and optionally the Country Code from the Query\
+ Variable Type: String
+ |
+
+
+
+ |
+ [FullAddress](#fulladdress)
+ |
+
+
+ Extract the Full Address from the Query\
+ Variable Type: Object
+ |
+
+
+
+ |
+ [Price](#price)
+ |
+
+
+ Extracts a Price from the Query\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [RawInput](#raw-input)
+ |
+
+
+ Extract the Input provided by the User, without any processing\
+ Variable Type: String
+ |
+
+
+
+ |
+ [Percentage](#percentage)
+ |
+
+
+ Extracts a Percentage from the Query\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [Quantity](#quantity)
+ |
+
+
+ Extract a Quantity from a Query\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [Color](#color)
+ |
+
+
+ Extracts a Color as both HEX and RGB codes from the Query\
+ Variable Type: Object
+ |
+
+
+
+ |
+ [TimeMeasurement](#time-measurement)
+ |
+
+
+ Extracts a time measurement as (ns, mu, ms, s, min, h, d, week, month, year) Units\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [WeightMeasurement](#weight-measurement)
+ |
+
+
+ Extracts a Weight Measurement as (mcg, mg, g, kg, oz, lb, mt, t) Units\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [CronSchedule](#cron-schedule)
+ |
+
+
+ Extracts a one-time or recurring schedule as a CRON Expression from the Query\
+ Variable Type: Object
+ |
+
+
+
+ |
+ [OperatingSystem](#operating-system)
+ |
+
+
+ Extracts the name of an Operating System (Windows, OSX, IOS, Android, Linux)\
+ Variable Type: Object
+ |
+
+
+
+ |
+ [QuantityofPeople](#quantity-of-people)
+ |
+
+
+ Extracts the Number of People in a Query\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [VolumeMeasurement](#volume-measurement)
+ |
+
+
+ Extracts a volume measurement as (mm3, cm3, ml, l, kl, m3, km3, tsp, Tbs, in3, fl-oz, cup, pnt, qt, gal, ft3, yd3) Units\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [TemperatureMeasurement](#temperature-measurement)
+ |
+
+
+ Extracts a Temperature Measurement as (C, K, F) Units\
+ Variable Type: Number
+ |
+
+
+
+ |
+ [Person](#person)
+ |
+
+
+ Extracts the name of a person(first and last names)\
+ Variable Type: Object
+ |
+
+
+
+ |
+ [DateTime](#datetime)
+ |
+
+
+ Extracts date and time relative to the current date\
+ Variable Type: Date
+ |
+
+
+
+
+
+
+
+### Single Choice
+
+The **Single Choice** is a type of input field that presents the user with a list of options to choose from. The user can only select **one** option from the list, and their choice is then stored as a value in a variable. This variable can be used later in your Workflow for further processing.
+
+
+Tip
+
+If the user enters text instead of clicking a button, the AI will check the text for any matching button labels. If it finds a match, it will handle the input as though the user had clicked that button.
+
+
+
+An example of Single Choice would be a survey question with multiple options, where the user selects one answer from the list.
+
+**Steps to use Single Choice Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Single Choice**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the selected option.
+4. Set the **Prompt message** property to a message that lists the available options for the user to choose from.
+5. Click on the **Advanced Configuration** to add Choices.
+
+Once the card is used, it will present the available options to the user and allow them to select only one. The selected option will be saved in the Workflow variable you specified, and you can use it in other parts of your Workflow to make decisions or take actions based on the user's choice.
+
+**Example**
+
+Let's say you want to ask the user about their preferred mode of transportation, and you have three options: car, bus, and bike. You can create a new capture information card with the following properties:
+
+```
+Type: Single Choice
+Variable name: preferredTransportation
+Prompt message: What is your preferred mode of transportation? Choose one from the following: car, bus, bike.
+```
+
+When the user selects their preferred mode of transportation, the Single Choice card will save the value in the `preferredTransportation` Workflow variable. You can then use this variable to tailor the conversation based on the user's choice.
+
+For example, if they choose bike, you can ask follow-up questions related to biking or suggest some scenic bike routes.
+
+You can also use the value of the `preferredTransportation` variable in transitions. For example, if the user selects car, you can move them to a node related to car-related services or if they choose bus, you can move them to a node related to public transportation schedules.
+
+### Multi Choice
+
+The **Multi Choice** type is a way to gather information from users by presenting them with a list of options to choose from. Users can select one or more options from the list.
+
+This type of capture information is useful in scenarios where you want to give users a set of choices to pick from, like selecting the toppings for a pizza or the colors for a shirt. It's a quick and easy way to collect information from users without having to ask them to type out their answers.
+
+**Steps to use Multi Choice Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Multi Choice**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted values.
+4. Set the **Prompt message** property to a message that provides a list of choices for the user to select from.
+5. Click on the **Advanced Configuration** to add Choices.
+
+Once the card is used, it will extract the selected options from the user's input and save them in the Workflow variable you specified. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Example**
+
+Let's say you want to ask the user what toppings they want on their pizza. You can create a new capture information card with the following properties:
+
+```
+Type: Multi Choice
+Variable name: pizzaToppings
+Prompt message: What toppings would you like on your pizza? Please select all that apply: pepperoni, mushrooms, onions, olives, sausage.
+```
+
+When the user enters their response, the Multi Choice card will extract the selected options and save them in the `pizzaToppings` Workflow variable. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+For example, if the user selects **pepperoni** and **mushrooms,** you can use the `pizzaToppings` variable to customise their order and display a message like **Your pizza with pepperoni and mushrooms is on the way!**
+
+### Boolean
+
+**Boolean** type extracts a binary value from the user's input and saves it in a variable of type Boolean. The extracted information can include values like true and false, agree and disagree, accept and decline, or any other binary values.
+
+**Steps to use Boolean Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Boolean**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted Boolean value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a binary value.
+5. Optionally, you can edit the Choices property if you want to customize the binary values that the user can select. By default, the choices are **Yes** and **No**. When the user provides an input, the system will extract either a **true** or **false** value based on whether the user selects **Yes** or **No**.
+
+**Example**
+
+Let's say you want to ask the user if they agree to the terms and conditions of service. You can create a new capture information card with the following properties:
+
+```
+Type: Boolean
+Variable name: agreeToTerms
+Prompt message: Do you agree to the terms and conditions of our service? Please enter 'yes' or 'no'.
+```
+
+When the user enters their response, the Boolean card will extract the binary value and save it in the **agreeToTerms** Workflow variable as either true or false. You can then use this variable in other parts of your Workflow to decide whether to proceed with the service or not.
+
+If the user agrees to the terms and conditions, you can submit their request or move them to the next node, but if they disagree, you can say something like 'Sorry to hear that' and end the conversation. This will display a message based on the user's response and whether they agreed to the terms and conditions or not.
+
+### Confirmation
+
+The **Confirmation** type is a way to ask the user to confirm or agree to something. For example, you might use this type to confirm a user's purchase, agreement to terms and conditions, or confirmation of an appointment. When the user responds, the Confirmation type extracts a binary value (either true or false) and saves it in a variable. This allows you to use the user's confirmation or agreement later in your bot's logic.
+
+**Steps to use Confirmation Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Confirmation**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted Boolean value.
+4. Set the **Prompt message** property to a message that prompts the user to confirm or agree to something.
+5. Optionally, you can edit the Choices property if you want to customize the binary values that the user can select. By default, the choices are **Accept** and **Decline**. When the user provides an input, the system will extract either a **true** or **false** value based on whether the user selects **Accept** or **Decline**.
+
+Once the card is used, it will automatically extract the confirmation from the user's input and save it in the Workflow variable you specified as a Boolean value (true or false). You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's confirmation.
+
+**Example**
+
+Let's say you want to ask the user if they want to proceed with a purchase. You can create a new capture information card with the following properties:
+
+```
+Type: Confirmation
+Variable name: proceedWithPurchase
+Prompt message: Are you sure you want to proceed with the purchase? Please enter 'Accept' or 'Decline'.
+```
+
+When the user enters their response, the Confirmation card will extract the confirmation and save it in the **proceedWithPurchase** Workflow variable as either true or false. You can then use this variable in other parts of your Workflow to decide whether to proceed with the purchase or not.
+
+If the user confirms they want to proceed with the purchase, you can move them to the payment process node, but if they decline, you can say something like 'No problem, maybe next time!' and end the conversation. This will display a message based on the user's response and whether they confirmed to proceed with the purchase or not.
+
+### Number
+
+The**Number** type extracts a numerical value from the user's input and saves it in a variable of type number.
+
+The user can enter any numerical value, like a whole number or a decimal, and the bot will recognize and store it as a number. This can be used for calculations or any other purpose where a numerical value is needed.
+
+**Steps to use Number Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Number**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted numerical value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a numerical value.
+
+Once the card is used, it will automatically extract the numerical value from the user's input and save it in the Workflow variable you specified as a numerical value (integer or decimal). You can then use this variable in other parts of your Workflow to perform calculations or take actions based on the user's response.
+
+**Example**
+
+Imagine you are creating an online store that sells products to customers. You want to ask the user to enter the quantity of a certain product they want to purchase. To do this, you can create a form with a field that uses the Number type to capture the user's input.
+
+For example, you can create a field with the following details:
+
+```
+Type: Number
+Variable name: productQuantity
+Prompt message: How many units of this product would you like to purchase?
+```
+
+When the user enters their response, the Number field will extract the numerical value and save it in the `productQuantity` variable as either an integer or decimal value. You can then use this variable in other parts of your Workflow to calculate the total cost of the purchase.
+
+For instance, if the product costs $10 per unit and the user entered **3** as the product quantity, you can calculate the total cost in an [Execute Code Card](./execute-code) as follows:
+
+```
+workflow.totalCost = workflow.productQuantity * $10
+```
+
+This will enable you to calculate the total cost of the purchase based on the user's input and display it to the user before they confirm their order.
+
+### Email Address
+
+The **EmailAddress** type is used to extract an email address value from the user's input and save it in a variable of type string. This allows you to use the extracted email address in other parts of your bot's logic, such as sending an email confirmation or storing the email address for future use. The email address can be in any valid email address format, including with special characters such as dots, hyphens, and underscores.
+
+**Steps to use Email Address Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **EmailAddress**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted email address value.
+4. Set the **Prompt message** property to a message that prompts the user to enter an email address.
+
+Once the card is used, it will automatically extract the email address value from the user's input and save it in the Workflow variable you specified as a string value. You can then use this variable in other parts of your Workflow to send emails or perform other actions based on the user's response.
+
+**Example**
+
+Let's say you want to ask the user for their email address so that you can send them a newsletter. You can create a new capture information card with the following properties:
+
+```
+Type: EmailAddress
+Variable name: userEmail
+Prompt message: Please enter your email address to subscribe to our newsletter.
+```
+
+When the user enters their email address, the EmailAddress card will extract the value and save it in the `userEmail` Workflow variable as a string. You can then use this variable in other parts of your Workflow to add the user to your newsletter subscription list or perform other actions based on the user's response.
+
+### Phone Number
+
+In this section, we'll discuss the **PhoneNumber** capture information type in Botpress. This type of capture information extracts only the phone number representing the user's input, excluding the country code, and saves it in a variable of type string.
+
+**Steps to use Phone Number Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **PhoneNumber**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted phone number value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a phone number.
+
+Once the card is used, it will automatically extract the phone number from the user's input and save it in the Workflow variable you specified as a string value. The extracted information won't include the country code, only the digits representing the phone number. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's phone number.
+
+**Example**
+
+Let's say you want to ask the user for their phone number to schedule a call with them. You can create a new capture information card with the following properties:
+
+```
+Type: PhoneNumber
+Variable name: userPhoneNumber
+Prompt message: Please enter your phone number so we can schedule a call with you.
+```
+
+When the user enters their response, the PhoneNumber card will extract the digits representing the phone number and save it in the userPhoneNumber Workflow variable as a string. You can then use this variable in other parts of your Workflow to schedule a call with the user.
+
+### FullAddress
+
+**FullAddress** extracts the full address information from the user's input and saves it in a variable of type object. The extracted information contains the country, city, street, zip code, and house number.
+
+**Steps to use Full Address Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **FullAddress**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted address information.
+4. Optionally, set the **Prompt message** property to a message that prompts the user to enter their address.
+5. Save the card.
+
+Once the card is saved, it will automatically extract the full address information from the user's input and save it in the Workflow variable you specified. You can then use this variable in other parts of your Workflow by referencing the specific fields in the address object using the following syntax: **`{{Workflow.variableName.country}}`**, **`{{Workflow.variableName.city}}`**, **`{{Workflow.variableName.street}}`**, **`{{Workflow.variableName.zip}}`**, and **`{{Workflow.variableName.number}}`**.
+
+**Example**
+
+Let's say you want to capture the user's full address to use in a shipping process. You can create a new capture information card with the following properties:
+
+```
+Type: FullAddress
+Variable name: shippingAddress
+Prompt message: **Please enter your full shipping address:**
+```
+
+When the user enters their address, the FullAddress card will extract the information and save it in the `shippingAddress` Workflow variable. You can then use this variable in other parts of your Workflow to complete the shipping process, such as sending an email confirmation to the user with their shipping details.
+
+Here's an example of how you can use the extracted information in a message:
+
+```
+Thank you for your order! Your shipping address is: {{workflow.shippingAddress.number}}
+{{workflow.shippingAddress.street}}, {{workflow.shippingAddress.city}}, {{workflow.shippingAddress.country}},
+{{workflow.shippingAddress.zip}}
+```
+
+This will display the user's full address in a clear and easy-to-read format for both the user and the bot.
+
+### Price
+
+**Price** extracts the price information from the user's input and saves it in a variable of type number. The extracted information contains the amount of money, regardless of the currency.
+
+**Steps to use Price Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Price**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted price information.
+4. Set the **Prompt message** property to a message that prompts the user to enter the price.
+5. Optionally, set the **Default value** property to a default price to be used if the user doesn't provide one.
+6. Save the card.
+
+Once the card is saved, it will automatically extract the price information from the user's input and save it in the Workflow variable you specified. You can then use this variable in other parts of your Workflow to perform calculations or other operations that require the price information.
+
+**Example**
+
+Let's say you want to capture the user's price information to process a payment. You can create a new capture information card with the following properties:
+
+```
+Type: Price
+Variable name: paymentAmount
+Prompt message: Please enter the payment amount:
+Default value: 0.00
+```
+
+When the user enters the price, the Price card will extract and save the information in the `paymentAmount` Workflow variable. You can then use this variable in other parts of your Workflow to process the payment, such as sending the payment information to a payment gateway.
+
+Here's an example of how you can use the extracted information in a message:
+
+```text
+Your payment amount is {{workflow.paymentAmount}}. Thank you for your payment!
+```
+
+This will display the user's payment amount in a clear and easy-to-read format for both the user and the bot.
+
+### Raw Input
+
+The **RawInput** extracts the user's input as it's and saves it in a variable of type string. The extracted information can include any type of user input, including text, numbers, and special characters.
+
+**Steps to use Raw Input Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Raw Input**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted user input.
+4. Set the **Prompt message** property to a message that prompts the user to enter their input.
+
+Once the card is used, it will automatically extract the user's input and save it in the Workflow variable you specified as a string value. You can then use this variable in other parts of your Workflow to process the user's input or display it back to them.
+
+**Example**
+
+Let's say you want your users to submit an issue for your product. You can create a new capture information card with the following properties:
+
+```
+Type: Raw Input
+Variable name: issueDescription
+Prompt message: Please describe the issue you are experiencing.
+```
+
+When the user enters the issue description, the Raw Input card will extract the user's input and save it in the `issueDescription` Workflow variable as a string value. You can then use this variable in other parts of your Workflow to log the issue or escalate it to the relevant team for resolution.
+
+You can create a message node with the following text:
+
+```text
+Thank you for reporting the issue: {{issueDescription}}. Our team will investigate the issue and get back to you with an
+update as soon as possible.
+```
+
+This will acknowledge the issue and provide the user with an estimated time frame for resolution.
+
+##### Answer from a Knowledge Base
+
+The Raw Input card can also be used to search for answers in a Knowledge Base (KB) and answer the user's question directly. You can have it search across all available KBs or limit the search to a specific KB.
+
+**Searching All Knowledge Bases**
+
+To enable the search across all available Knowledge Bases when the user asks a question:
+
+1. Create a new capture information card with the Type set to **Raw Input**.
+2. Make sure the "Search in all KBs" option is selected.
+3. In the **Prompt message** property, enter a message that encourages the user to input their question (e.g., “What would you like to know?”).
+4. Store the user's input in a variable by setting the **Variable name** property (e.g., `userQuery`) if you want to use it later.
+
+Once set up, the bot will automatically search all configured Knowledge Bases for the user's inputted question and display the answer, provided that the Knowledge Agent's manual answering feature isn't enabled.
+
+**Searching a Particular Knowledge Base**
+
+For more targeted information retrieval, you may want to search within a specific KB:
+
+1. Create a new capture information card with the Type set to **Raw Input**.
+2. Deselect the "Search in all KBs" option.
+3. Provide the name of the KB you wish to search in the "KBs to search in" input field.
+4. In the **Prompt message** property, enter a prompt directing the user to ask their question.
+5. Set the **Variable name** property to save the user's query (e.g., `userQuerySpecific`) if you want to use it later.
+
+After the user submits their question, the bot will automatically conduct a search within the specified Knowledge Base and display the relevant answer. This happens seamlessly without the need for an action card to trigger the search, assuming that manual answering is turned off for the Knowledge Agent.
+
+### Percentage
+
+The **Percentage** extracts the decimal representing the percentage from the user's input and saves it in a variable of type number. The extracted information can include values like 50%, 75%, or any other percentage.
+
+**Steps to use Percentage Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Percentage**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted percentage value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a percentage.
+
+Once the card is used, it will automatically extract the decimal value representing the percentage from the user's input and save it in the Workflow variable you specified as a number value. You can then use this variable in other parts of your Workflow to make calculations or take actions based on the user's response.
+
+**Example**
+
+Let's say you want to ask the user what percentage discount they would like to apply to their purchase. You can create a new capture information card with the following properties:
+
+```
+Type: Percentage
+Variable name: discountPercentage
+Prompt message: **Please enter the percentage discount you would like to apply to your purchase.**
+```
+
+When the user enters their response, the Percentage card will extract the decimal value representing the percentage and save it in the `discountPercentage` Workflow variable as a number. You can then use this variable in other parts of your Workflow to calculate the discount or take actions based on the user's desired discount.
+
+For example, if the user entered 50%, you could calculate the discount amount as follows:
+
+```html
+discountAmount = totalPrice * (discountPercentage / 100)
+```
+
+This will calculate the discount amount based on the user's desired discount percentage and the total price of the purchase.
+
+### Quantity
+
+The **Quantity** extracts the quantity information from the user's input and saves it in a variable of type number. For example, if the user inputs "I want to buy 5 apples" or "Give me 5 kilograms of apples", the function will extract the number 5 and store it as a numerical value, without regard to the different units of measurement used. This allows you to work with the quantity of the item, regardless of how the user expressed it.
+
+**Steps to use Quantity Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Quantity**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted quantity information.
+4. Set the **Prompt message** property to a message that prompts the user to enter the quantity.
+
+Once the card is saved, it will automatically extract the quantity information from the user's input and save it in the Workflow variable you specified. You can then use this variable in other parts of your Workflow by referencing it using the following syntax: \***\*`{{Workflow.variableName}}`\*\***.
+
+**Example**
+
+Let's say you want to capture the user's desired quantity of a product. You can create a new capture information card with the following properties:
+
+```
+Type: Quantity
+Variable name: productQuantity
+Prompt message: **How many units of the product do you want?**
+```
+
+When the user enters a valid quantity, the Quantity card will extract and save the information in the `productQuantity` Workflow variable as a number. You can then use this variable in other parts of your Workflow to calculate the total price or to check the stock availability.
+
+Here's an example of how you can use the extracted information in a message:
+
+```text
+Thank you for your order! Your total price is {{workflow.productQuantity * productPrice}}.
+```
+
+This will display the total price to the user based on the quantity they entered and the price of the product.
+
+### Color
+
+The **Color** type extracts the color information from the user's input and saves it in a variable of type object. The extracted information contains the colour name, hexadecimal code, and RGB values.
+
+**Steps to use Color Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Color**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted colour information.
+4. Set the **Prompt message** property to a message that prompts the user to enter a colour.
+
+Once the card is called will automatically extract the colour information from the user's input and save it in the Workflow variable you specified. You can then use this variable in other parts of your Workflow by referencing the specific fields in the colour object using the following syntax: **`{{workflow.variableName.colorName}}`**, **`{{workflow.variableName.hexCode}}`**, and **`{{workflow.variableName.rgb}}`**.
+
+**Example**
+
+Let's say you want to capture the user's favourite colour to use in a marketing campaign. You can create a new capture information card with the following properties:
+
+```
+Type: Color
+Variable name: favoriteColor
+Prompt message: Please enter your favourite colour:
+```
+
+When the user enters their favourite colour, the Color card will extract the information and save it in the `favoriteColor` Workflow variable. You can then use this variable in other parts of your Workflow to customise your marketing campaigns, such as using the colour in promotional materials or emails.
+
+Here's an example of how you can use the extracted information in a message:
+
+```html
+Thank you for telling us your favourite colour! We love {{workflow.favoriteColor.colorName}} too. The hexadecimal code
+for {{workflow.favoriteColor.colorName}} is {{workflow.favoriteColor.hexCode}} and the RGB values are
+{{workflow.favoriteColor.rgb}}.
+```
+
+This will display the user's favourite colour and its associated information in a personalised message, making the interaction with the bot more engaging and memorable.
+
+### Time Measurement
+
+The **TimeMeasurement** type extracts date/duration values from the user's input and save it in a variable of type **Number** after converting it to the chosen format. The extracted information can include values like next week, in a month, after two months, in 15 days, in 2 working days, etc. This information can be useful for scheduling appointments, setting reminders, and much more.
+
+**Steps to use Time Measurement Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Time Measurement**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted time measurement value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a date/duration value.
+
+Once the card is used, it will automatically extract the date/duration value from the user's input and save it in the Workflow variable you specified as a number value. The time measurement value will be converted to the chosen format (nanoseconds, microseconds, milliseconds, seconds, minutes, hours, days, weeks, months, or years). You can then use this variable in other parts of your Workflow to schedule appointments or set reminders.
+
+**Available Formats**
+
+The following formats are available for the extracted time measurement value:
+
+`ns` (nanoseconds)\
+`mu` (microseconds)\
+`ms` (milliseconds)\
+`s` (seconds)\
+`min` (minutes)\
+`h` (hours)\
+`d` (days)\
+`week` (weeks)\
+`month` (months)\
+`year` (years)
+
+You can choose any of these formats based on your requirement.
+
+**Example**
+
+Let's say you want to schedule a meeting with a user based on their availability. You can create a new capture information card with the following properties:
+
+```text
+Type: Time Measurement
+Variable name: meetingTime
+Prompt message: When are you available for a meeting? Please enter a date or duration (for example: next week, in 2 days, in 30 minutes).
+```
+
+When the user enters their response, the Time Measurement card will extract the time measurement value and save it in the `meetingTime` Workflow variable as a number value in the chosen format. You can then use this variable in other parts of your Workflow to schedule the meeting accordingly.
+
+If the user is available at the specified time, you can schedule the meeting and confirm the details with the user. If not, you can ask for their availability again.
+
+This will allow you to schedule meetings with users based on their availability and improve their experience with your service.
+
+### Weight Measurement
+
+The **WeightMeasurement** extracts weight information from the user's input and saves it in a variable of type number after converting it to the chosen format. The available formats are `mcg`, `mg`, `g`, `kg`, `mt`, `oz`, `lb`, `t`.
+
+**Steps to use Weight Measurement Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Weight Measurement**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted weight value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a weight.
+
+Once the card is used, it will automatically extract the weight information from the user's input and save it in the Workflow variable you specified as a number value. The value is converted to the chosen format which is selected during the configuration of the card. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Available Formats**
+
+The available weight measurement formats are:
+
+
+
+
+ | mcg (microgram) |
+ mg (milligram) |
+ g (gram) |
+ kg (kilogram) |
+
+
+
+
+ | mt (metric ton) |
+ oz (ounce) |
+ lb (pound) |
+ t (ton) |
+
+
+
+
+**Example**
+
+Let's say you want to ask the user for their weight in kilograms. You can create a new capture information card with the following properties:
+
+```
+Type: Weight Measurement
+Variable name: userWeight
+Prompt message: Please enter your weight in kilograms.
+```
+
+When the user enters their response, the Weight Measurement card will extract the weight information and convert it to kilograms, saving it in the `userWeight` Workflow variable as a number value. You can then use this variable in other parts of your Workflow to decide what to do based on the user's response.
+
+You can ask the user if they want to proceed if their weight is over a certain limit or if it falls under a certain range. You can also display the weight measurement in different formats by using a formatted node.
+
+This will display the user's weight in the desired format and provide relevant information based on their response.
+
+### Cron Schedule
+
+The **CronSchedule** type takes a specific interval of time that a user inputs and convert it into a format that a computer program can understand. This interval can be things like **every 5 minutes** or **once a day at 3pm.**
+
+The cron schedule then saves this interval in two ways: first, in a format that follows the cron convention (which is a standard way of representing time intervals in programming); and second, as a Boolean value that indicates whether the interval should be repeated or not (for example, if the interval is "every 5 minutes," the cron schedule would set the repeatable property to true, whereas if the interval is "once a day at 3pm," the cron schedule would set the repeatable property to false).
+
+This makes it easier for developers to program applications that need to run certain tasks at specific intervals of time.
+
+**Steps to use cron schedule field**
+
+1. Create a new capture information card.
+2. Set the Type property to **cron schedule**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted cron interval.
+4. Set the **Prompt message** property to a message that prompts the user to enter the desired interval value.
+
+Once the card is used, it will automatically extract the interval value from the user's input and save it in the Workflow variable you specified as an object containing the cron interval and the **repeatable** Boolean value.
+
+**Example**
+
+Let's say you want to ask the user for a cron schedule to trigger a certain event. You can create a new capture information card with the following properties:
+
+```
+Type: Cron Schedule
+Variable name: cronSchedule
+Prompt message: Please enter the interval in cron format, for example: '0 \* \* \* \*' for every hour, and indicate whether this should be repeated or not with 'true' or 'false'.
+```
+
+When the user enters their response, the cron Schedule card will extract the interval value and save it in the `cronSchedule` Workflow variable as an object with two properties: the **cron** value, which represents the extracted interval in a cron format, and the **repeatable** Boolean value, which indicates whether the interval should be repeated or not.
+
+You can then use this variable in other parts of your Workflow to set up the event trigger according to the user's input.
+
+### Operating System
+
+The **OperatingSystem** type extracts the operating system the user is using from their input and saves it in a variable of type object. This information can be useful for troubleshooting issues specific to certain operating systems or for tailoring responses based on the user's operating system.
+
+**Steps to use Operating System Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Operating System**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted operating system.
+4. Set the **Prompt message** property to a message that prompts the user to enter their operating system.
+
+Once the card is used, it will automatically extract the operating system from the user's input and save it in the Workflow variable you specified as an object. The extracted information can include the name and version of the operating system.
+
+**Example**
+
+Let's say you want to ask the user about the operating system they're using to access your website. You can create a new capture information card with the following properties:
+
+```
+Type: OperatingSystem
+Variable name: userOS
+Prompt message: **What operating system are you using to access our website?
+```
+
+When the user enters their response, the Operating System card will extract the information and save it in the **userOS** Workflow variable as an object that includes the name and version of their operating system.
+
+You can then use this variable in other parts of your Workflow to tailor responses or troubleshoot issues specific to their operating system.
+
+### Quantity of People
+
+The **QuantityofPeople** type extracts a number representing the quantity of people from the user's input and saves it in a variable of type **Number**. The extracted information can include values like 1, 2, or 3.
+
+For example, if you are building a reservation system for a restaurant, you can use the QuantityofPeople type to ask the user how many people will be dining, and then save that number as a variable. This variable can then be used to ensure that the restaurant has enough seats available for the group, or to calculate the total cost of the meal based on the number of people.
+
+**Steps to use Quantity of People Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **QuantityofPeople**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted number value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a number representing the quantity of people.
+
+Once the card is used, it will automatically extract the number value from the user's input and save it in the Workflow variable you specified as a number. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Example**
+
+Let's say you want to ask the user how many people will be attending an event. You can create a new capture information card with the following properties:
+
+```
+Type: Quantity Of People
+Variable name: numberOfAttendees
+Prompt message: How many people will be attending the event?
+```
+
+When the user enters their response, the Quantity Of People card will extract the number value and save it in the **numberOfAttendees** Workflow variable. You can then use this variable in other parts of your Workflow to decide how many seats to reserve or how much food to order.
+
+If the user enters a number greater than the available seats or food quantity, you can respond with something like 'Sorry, we don't have enough seats/food for that many people' and ask the user to enter a smaller number.
+
+This will display a message based on the user's response and the availability of seats or food.
+
+### Volume Measurement
+
+The **VolumeMeasurement** extracts a volume value from the user's input and saves it in a variable of type number. The extracted value can be converted to one of the several available formats based on the user's choice.
+
+**Steps to use Volume Measurement Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **VolumeMeasurement**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted volume value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a volume value.
+
+Once the card is used, it will automatically extract the volume value from the user's input and save it in the Workflow variable you specified as a number value. You can then use this variable in other parts of your Workflow to perform calculations or use the value in responses to the user.
+
+**Available Formats**
+
+The following volume formats are available for conversion:
+
+
+
+
+ |
+ Cubic millimeters (mm3)
+ |
+
+ Cubic centimeters (cm3)
+ |
+ Milliliters (ml) |
+ Centiliters (cl) |
+
+
+
+
+ | Deciliters (dl) |
+ Liters (l) |
+ Kiloliters (kl) |
+
+ Cubic meters (m3)
+ |
+
+
+ |
+ Cubic kilometers (km3)
+ |
+ Teaspoons (tsp) |
+ Tablespoons (Tbs) |
+
+ Cubic inches (in3)
+ |
+
+
+ | Fluid ounces (fl-oz) |
+ Cups (cup) |
+ Pints (pnt) |
+ Quarts (qt) |
+
+
+ | Gallons (gal) |
+
+ Cubic feet (ft3)
+ |
+
+ Cubic yards (yd3)
+ |
+ |
+
+
+
+
+**Example**
+
+Let's say you want to ask the user about the volume of a liquid they want to order. You can create a new capture information card with the following properties:
+
+```
+Type: VolumeMeasurement
+Variable name: liquidVolume
+Prompt message: What is the volume of liquid you want to order? Please enter a number and choose a volume format from the following list: mm3, cm3, ml, cl, dl, l, kl, m3, km3, tsp, Tbs, in3, fl-oz, cup, pnt, qt, gal, ft3, yd3.
+```
+
+The **Volume Measurement** type extracts the volume value and save it in the `liquidVolume` Workflow variable as a number value. The value will be converted to the format specified by the user. You can then use this variable in other parts of your Workflow to perform calculations or use the value in responses to the user.
+
+For example, you could use the `liquidVolume` variable to calculate the price of the liquid based on the volume and price per unit of volume, or you could use it in response to the user like **Thank you for ordering** `{{workflow.liquidVolume}}` **ml of liquid.** Your order will be delivered soon.
+
+### Temperature Measurement
+
+The **TemperatureMeasurement** type extracts a temperature value from the user's input and saves it in a variable of type **Number**. The extracted temperature can be in any of the available formats: Celsius, Kelvin, or Fahrenheit.
+
+**Steps to use Temperature Measurement Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Temperature Measurement**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted temperature value.
+4. Set the **Prompt message** property to a message that prompts the user to enter a temperature value in any of the available formats.
+
+Once the card is used, it will automatically extract the temperature value from the user's input, convert it to the chosen format, and save it in the Workflow variable you specified as a number. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Available Formats**
+
+There are three temperature formats available in the **TemperatureMeasurement** capture information type. These are: Celsius (°C), Kelvin (K) & Fahrenheit (°F)
+
+You can choose the format you want to use in the prompt message property of the capture information card.
+
+**Example**
+
+Let's say you want to ask the user for their body temperature. You can create a new capture information card with the following properties:
+
+```
+Type: TemperatureMeasurement
+Variable name: bodyTemperature
+Prompt message: Please enter your body temperature in Celsius (°C), Kelvin (K), or Fahrenheit (°F)
+```
+
+When the user enters their response, the Temperature Measurement card will extract the temperature value, convert it to the specified format, and save it in the `bodyTemperature` Workflow variable as a **Number**. You can then use this variable in other parts of your Workflow to decide what action to take based on the user's body temperature.
+
+If the user's body temperature is above the normal range, you can send them to a doctor's appointment node. If not, you can proceed with the conversation as usual.
+
+This will display a message based on the user's response and the action you decide to take based on their body temperature.
+
+### Person
+
+The **Person** type is used to extract the name of a person from the user's input, such as when you ask the user for the name of a contact or a customer. Once the user enters the name, the Person type extracts the first and last names and saves them in a variable of type **Object**.
+
+This extracted information can be used in other parts of your Workflow to personalize messages or perform actions specific to that person, such as sending them an email or adding them to a mailing list.
+
+**Steps to use Person Field**
+
+1. Create a new capture information card.
+2. Set the Type property to **Person**.
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted name information.
+4. Optionally, set the **Prompt message** property to a message that prompts the user to enter their name.
+5. Save the card.
+
+Once the card is saved, it will automatically extract the person's name information from the user's input and save it in the Workflow variable you specified.
+
+You can then use this variable in other parts of your Workflow by referencing the specific fields in the name object using the following syntax:
+
+```text
+{{workflow.variableName.first}} and {{workflow.variableName.last}}
+```
+
+**Example**
+
+Let's say you want to capture the user's name to personalise a message. You can create a new capture information card with the following properties:
+
+```
+Type: Person
+Variable name: userName
+Prompt message: What's your name?
+```
+
+When the user enters their name, the Person card will extract and save the information in the **userName** Workflow variable. You can then use this variable in other parts of your Workflow to personalise your messages, such as greeting the user by name.
+
+Here's an example of how you can use the extracted information in a message:
+
+```text
+Hello {{workflow.userName.first}}, welcome to our website!
+```
+
+This will display a personalised greeting to the user with their first name.
+
+### Datetime
+
+The **Datetime** capture information type in Botpress. This type of capture information extracts a date or duration value from the user's input and saves it in a variable of type **Object**. The extracted information can include values like **next week,** **in a month,** **after two months,** **in 15 days,** **2 working days,** or any other date or duration value.
+
+**Steps to use Datetime Field**
+
+1. Pick the **Datetime** Capture Information Card from the Cards.
+2. (Optional) - Add a question to ask. (for example: when would you like to book an appointment?)
+3. Store the output in a variable.
+
+Once the card is used, it will automatically extract the date or duration value from the user's input and save it in the Workflow variable you specified as an object. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Example**
+
+Let's say you want to ask the user for their preferred date of booking a hotel room. You can create a new capture information card with the following properties:
+
+```
+Type: Datetime
+Variable name: bookingDate
+Prompt message: When would you like to book the room? Please enter a date or duration (e.g., next week, in a month, after two months, in 15 days, 2 working days).
+```
+
+When the user enters their response, the Datetime card will extract the date or duration value and save it in the `bookingDate` Workflow variable as an object. You can then use this variable in other parts of your Workflow to decide when to book the room or provide available dates for the user to choose from.
+
+You can check the user's preferred booking date against your available dates to ensure the room is available for booking on that day. If the room isn't available, you can offer other available dates or suggest another hotel that's available on the preferred date.
+
+##### Formatting Date
+
+```javascript
+const date = luxon.DateTime.fromJSDate(workflow.date)
+// Default format of date is 2023-09-27T00:00:00.000Z
+
+// Example 1: Display a Friendly, Human-readable Date Format
+const friendlyFormat = date.toFormat('LLLL dd, yyyy')
+console.log(`📅 Your requested date is: ${friendlyFormat}.`)
+// Output: 📅 Your requested date is: September 27, 2023.
+
+// Example 2: Display the Day of the Week
+const dayOfWeek = date.toFormat('EEEE')
+console.log(`📆 It falls on a: ${dayOfWeek}.`)
+// Output: 📆 It falls on a: Wednesday.
+
+// Example 3: Display the Date in Numeric Format
+const numericDateFormat = date.toFormat('dd-MM-yyyy')
+console.log(`🗓 Numeric Format: ${numericDateFormat}.`)
+// Output: 🗓 Numeric Format: 27-09-2023.
+
+// Example 4: Display the Date with Slashes
+const slashDateFormat = date.toFormat('yyyy/MM/dd')
+console.log(`📌 Slash Format: ${slashDateFormat}.`)
+// Output: 📌 Slash Format: 2023/09/27.
+
+// Example 5: Display the Date with Day and Month Name
+const dayMonthNameFormat = date.toFormat('EEEE, dd of LLLL')
+console.log(`🌟 Day and Month Name Format: ${dayMonthNameFormat}.`)
+// Output: 🌟 Day and Month Name Format: Wednesday, 27 of September.
+```
+
+### Wait for User Input
+
+The **Wait for User Input** type is used to pause the Workflow of a conversation until the user enters a specific input. This can be useful when you want to wait for the user to enter a specific input before proceeding with the conversation.
+
+**Steps to use Wait for User Input Field**
+
+1. Drag and drop the **Wait for User Input** card into your node.
+2. You can use `{{event.preview}}` to display the fetched user's response after the user enters the input.
+
+### File Upload
+
+The **File Upload** type allows users to upload a file through the bot interface. Once the file is uploaded, the bot captures the URL of the uploaded file as a string variable.
+
+##### Configuration Steps:
+
+1. **Enable File Upload in Webchat Settings**:
+ - Navigate to the **Webchat** settings in Botpress Studio.
+ - Under the **General** tab, find the option labeled **Allow user file upload**.
+ - Toggle the setting to **Enabled**.
+
+2. **Set Up the Capture Information Card**:
+ - In the **Capture Information** card, select **File** as the **Type of value to extract**.
+ - Define the **Question to ask the user**, such as "Please upload the file you want to share."
+ - Specify the variable in **Store result in** where the file URL will be stored (e.g., `workflow.filePath`).
+
+##### Example:
+
+If the user uploads a file, the bot will save the file's URL to the specified variable. You can then use this variable in subsequent Workflows, such as storing the file URL in a database or sending it to an API.
+
+## Custom Prompt Fields
+
+### Entity - Regex
+
+The **Entity - Regex** type of capture information uses regular expressions to extract specific patterns of information from the user's input and saves it in a variable of type **String**. It's particularly useful for capturing sensitive information like credit card numbers, which have distinct patterns.
+
+**Steps to use Regex Field**
+
+1. Create a new entity in the **Entities** section of your Botpress instance with a custom regular expression that matches the pattern of the information you want to capture.
+2. Create a new capture information card.
+3. Set the Type property to **Entity Regex**.
+4. Select the entity you created in Step 1 from the **Entity** dropdown.
+5. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted information.
+6. Set the **Prompt message** property to a message that prompts the user to enter the information you want to capture.
+
+Once the card is used, it will automatically extract the information that matches the regular expression pattern from the user's input and save it in the Workflow variable you specified as a string. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's input.
+
+**Example**
+
+Let's say you want to ask the user for their credit card number. You can create a new entity with a regular expression that matches the pattern of a credit card number, such as **/(\\d\{4}-)\{3}\\d\{4}/** for a 16-digit credit card number in the format **XXXX-XXXX-XXXX-XXXX**. You can then create a new capture information card with the following properties:
+
+```
+Type: Entity Regex
+Entity: Credit Card Number (the entity you created in step 1)
+Variable name: creditCardNumber
+Prompt message: Please enter your credit card number in the format XXXX-XXXX-XXXX-XXXX.
+```
+
+When the user enters their credit card number, the Entity Regex card will extract the credit card number that matches the regular expression pattern and save it in the **creditCardNumber** Workflow variable as a string. You can then use this variable in other parts of your Workflow to perform actions like validating the credit card number or sending it to a payment gateway.
+
+It's important to note that the **Contains sensitive data** property is available for Entity Regex type, which will mask the data by \* before saving it in the database, making it more secure.
+
+### Entity - List
+
+In this section, we'll discuss the **Entity - List** capture information type in Botpress. This type of capture information extracts specific pieces of information from the user's input based on matching it with entries (or synonyms) in a custom entity list. This can be useful when you want to capture specific information like a person's name, location, or product name.
+
+**Steps to use List Field**
+
+1. Create a new entity list under the library -> entities section.
+2. Add entries to the entity list and their synonyms.
+3. Create a new capture information card.
+4. Set the Type property to **Entity List**.
+5. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted information.
+6. Set the **Prompt message** property to a message that prompts the user to enter information that matches the entity list.
+
+Once the card is used, it will automatically extract the information that matches an entry (or one of its synonyms) in the custom entity list from the user's input and save it in the Workflow variable you specified. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's response.
+
+**Fuzzy matching options**
+
+Botpress offers three options for fuzzy matching:
+
+- **Strict**: No errors allowed.
+- **Medium**: Tolerates up to one error in words of four characters or more.
+- **Loose**: Tolerates up to two errors in words of four characters or more.
+
+This means that even if the user makes a typo or a slight error, the system can still match the input with an entry in the entity list.
+
+**Example**
+
+Let's say you want to ask the user for their favorite type of pizza. You can create a new entity list with entries like **Pepperoni,** **Hawaiian,** **Margherita,** and **Vegetarian.** Then, create a new capture information card with the following properties:
+
+```
+Type: Entity List
+Variable name: favoritePizza
+Prompt message: **What's your favorite type of pizza? Please enter the name of one of our popular pizza types.
+```
+
+When the user enters their response, the Entity List card will extract the information that matches an entry (or synonym) in the custom entity list and save it in the `favoritePizza` Workflow variable. You can then use this variable in other parts of your Workflow to make decisions or take actions based on the user's favorite pizza type.
+
+For example, you could use this variable to direct the user to the pizza ordering process, or to suggest additional toppings based on their selection.
+
+## Advanced Configuration
+
+### Retries
+
+The **Retries** setting helps the bot handle situations when it doesn't understand what the user is saying. It allows the bot to ask the user to provide the information again in a different way. This can improve the user's experience with the bot, increase engagement, and help the bot handle more conversations before giving up.
+
+**Number of retries**
+
+This is the maximum number of times the bot will ask the user to provide the information again before giving up and moving to the next card in the conversation or triggering the failure transition if enabled.
+
+**Retry message**
+
+This is the message that the bot will show to the user each time they fail to answer the question. It will ask the user to provide the information again in a different way. If the capture has predefined choices the retry message will contain the buttons again.
+
+You can also add variables to this message using the following syntax:
+
+```
+Hello @workflow.userName.first, we did not get your number right, please enter it again!
+```
+
+**Pro Tip**
+
+To give your users the best experience, you can combine the **Retries** option with the **Add transition to handle failure** flag. This will help the bot gracefully handle situations when it can't understand the user's input.
+
+**Example 1:**
+
+Let's say you have a card that asks the user to choose between **Food** and **Drinks**. If you set the **Number of retries** to 0 and the **Add transition to handle failure** flag is turned on, then if the user says **I want Cars**, the bot will redirect the user directly to the failure transition, where you can show a message like **Sorry, I didn't understand that**.
+
+**Example 2:**
+
+Now, let's change the example to have the **Number of retries** set to 2 and the **Retry message** set to **Sorry, I didn't understand that, try to choose from the choices**, and the **Add transition to handle failure** flag turned on. If the user says, **I want Cars**, the bot will respond with **Sorry, I didn't understand that. Try to choose from the choices**, and show the choices again.
+
+If the user provides another message that isn't related to the choices, the bot will retry again, up to a maximum of two retries. If the user still fails to provide the required information after the maximum retries, the bot will redirect the user directly to the failure transition, where you can have a message like **Sorry, I didn't understand that**.
+
+### Validation
+
+The **Validation** setting allows you to verify that the user's input meets certain criteria before proceeding with the conversation. This can help ensure that the information collected is accurate and relevant to the conversation.
+
+**Properties**
+
+**1. Label**
+
+The label property allows you to generate validation code based on plain natural language instructions. This can make it easier to set up the validation rules without needing to write code.
+
+**2. Code**
+
+If you prefer to write your own validation code, you can use the code property. This property allows you to write code to evaluate the user's input and determine whether it meets the validation criteria.
+
+**3. Validation failed message**
+
+If the user's input fails validation, you can customise the message that the bot sends to inform the user of the validation failure.
+
+**Steps to use Validation**
+
+To use the validation feature, you can add the validation properties to the Capture Information card in the Botpress interface. You can choose to use the Label or Code property to set up the validation rules.
+
+Once the validation rules are set up, the user's input will be evaluated before proceeding with the conversation. If the input meets the validation criteria, the conversation will continue normally. If the input fails validation, the bot will send a message with the validation failed message you have specified.
+
+**Example 1:**
+
+Suppose you have a Capture Information card that asks the user for their age. You want to ensure that the user enters a number between 18 and 100. You can use the following validation code in the **Validation** section of the card:
+
+```ts
+function validate(input: string): boolean
+{
+ const age = parseInt(input) if (isNaN(age))
+ { return false }
+ return age >= 18 && age <= 100
+}
+```
+
+This code first tries to parse the user's input as a number. If the input isn't a valid number, the code returns **false**. Otherwise, it checks if the age is between 18 and 100 and returns **true** if it is.
+
+**Example 2:**
+
+Suppose you have a Capture Information card that asks the user for their email address. You want to ensure that the user enters a valid email address format. You can use the following validation code in the **Validation** section of the card:
+
+```ts
+function validate(input: string): boolean {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
+ return emailRegex.test(input)
+}
+```
+
+This code uses a regular expression to check if the user's input matches the format of a valid email address. If the input matches the format, the code returns `true`. Otherwise, it returns `false`.
+
+### Extract from History
+
+The **Extract from History** setting allows the bot to extract values from previous messages in the conversation history. This can help the bot better understand the user's input and provide more accurate responses.
+
+**Property**
+
+**Number of messages from history to extract from**
+
+This property determines how many messages in the conversation history the bot will try to extract the value from. A value of **0** means that the bot won't look back in the conversation history and will only use the user's most recent message. A value of **2** means that the bot will extract the value from the user's previous two messages.
+
+**Example:**
+
+Let's say you have a Capture Information card that asks the user for their favorite color. If the user has already mentioned their favorite color earlier in the conversation, you can use the **Extract from History** feature to extract the value from their previous message.
+
+If you set the **Number of messages from history to extract from** to **1**, the bot will extract the value from the user's previous message. If you set it to **2**, the bot will extract the value from the message before that too.
+
+For example, if the user said **My favorite color is blue** earlier in the conversation and you set the **Number of messages from history to extract from** to **1**, the bot will extract **blue** as the user's favorite color without asking the user again. This can save time and improve the user experience by avoiding repetitive questions.
+
+### Cancellation
+
+The **Cancellation** setting can be used to break out of the conversation and cancel the Capture Information card. This can enhance the user's experience with the bot, making the conversation feel more natural and increasing engagement.
+
+**Properties**
+
+**User can cancel the capture**
+
+With this option turned on, users can cancel the Capture Information card at any time during the conversation.
+
+**Confirm before cancelling**
+
+If you turn on this option, users will be asked to confirm whether they want to cancel the Capture Information card before it's cancelled.
+
+**Confirm cancel message**
+
+This option allows you to customise the message that the bot sends to confirm the user's decision to cancel the Capture Information card.
+
+**Example 1:**
+
+Suppose you have a Capture Information card that asks the user for their name and email address. If the user decides to cancel the conversation, the **User can cancel the capture** option will allow them to do so easily.
+
+**Example 2:**
+
+If you turn on the **Confirm before cancelling** option, the bot will ask the user if they're sure they want to cancel the Capture Information card before it's cancelled. If the user confirms the cancellation, the bot will send a message that you can customise using the **Confirm cancel message** option.
+
+### Choices
+
+The **Choices** setting is used to offer a list of options to the user as a response to a Capture Information card. This can be useful when you want to restrict the user's input to a specific set of values or provide them with a list of options to choose from quickly.
+
+You could add fixed options or add variables to each choice to make them dynamic. You can also render the list of choices dynamically by toggling the SuperText input and adding an array variable with the following format:
+
+```js
+;[
+ {
+ label: 'French',
+ value: 'fr',
+ },
+ {
+ label: 'English',
+ value: 'en',
+ },
+]
+```
+
+
+ Limit
+
+If you add more than 5 choices, they will be rendered as a Dropdown/List instead of buttons. This number may vary by channel.\{' '} The choices labels shouldn't be longer than 20 characters otherwise they will get cut in some channels.
+
+
+
+
+ To show a **dropdown** when you have **five or fewer** choices, or to control options entirely in code, see [Dropdown
+ menus](/studio/guides/how-to/dropdown-menus).
+
+
+
+Note
+
+Choices are only available for **Single Choice**, **Multiple Choice**, **Boolean**, **Confirmation** and **Raw Input**Capture cards.
+
+
+
+**Example**
+
+Suppose you have a Capture Information card that asks the user to select their preferred mode of transportation - Car, Bus or Train. If you turn on the Choices option and specify these three options, the user will be presented with these options to choose from.
+
+### Advanced
+
+1. Add transition to handle failure
+
+This is a yes/no flag that determines whether a transition should be added to handle cases where the Capture Information card fails to retrieve information from the user.
+
+**Example**
+
+If this flag is set to **Yes** and the Capture Information card fails to capture the required information, it will transition to the failure transition where a message can be displayed to the user, such as **Sorry, I didn't understand that. Please try again**.
+
+2. Skip if variable is already filled
+
+This is a flag that determines whether the Capture Information card should be skipped if the variable assigned to it already has a value.
+
+**Example**
+
+If this flag is set to **Yes** and the variable already has a value, the Capture Information card will be skipped entirely, and the conversation will proceed to the next node.
+
+This flag can be useful in scenarios where a user may have already provided the required information in a previous conversation with the bot.
+
+Combining these two flags can help improve the user experience with the bot by allowing for smoother conversation Workflows and avoiding unnecessary repetition.
+
+## Prompt Chaining
+
+Prompt Chaining allows you to extract multiple values from a single user message using multiple Capture Information cards in sequence. If a value wasn't found, the respective Capture Information card will ask for its value.
+
+**Chaining Multiple Prompts**
+
+To chain multiple Capture Information cards together, you need to follow these steps:
+
+1. Add the first Capture Information card to the Workflow.
+2. Set the Type property to the type of information you want to capture (e.g., **Person Name**).
+3. Set the **Variable name** property to the name of the Workflow variable you want to use to store the extracted information (e.g., **Person Name**).
+4. Set the **Prompt message** property to a message that prompts the user to enter the information (e.g., **Please enter your full name**).
+5. Set the **Extract from history** property to **1**.
+6. Add the next Capture Information card to the Workflow.
+7. Repeat steps 1-6 for each additional Capture Information card you want to add, making sure to use a different variable name for each one.
+
+Once the user enters a value, it will automatically extract the requested information from the user's message using each Capture Information card in sequence. If a value isn't found for a particular Capture Information card, it will ask the user for the value before proceeding to the next node/card.
+
+You can then use the extracted variables in other parts of your Workflow by referencing the specific variable names using the following syntax: **`{{workflow.variableName}}`**.
+
+**Example**
+
+Let's say you want to capture a user's full name, email address, and phone number. You can create a new Workflow with the following steps:
+
+1. Add a Capture Information card to the Workflow with the following properties:
+
+```
+Type: Fullname
+Variable name: fullname
+Prompt message: Please enter your full name
+Extract from history: 1
+```
+
+2. Add a second Capture Information card to the Workflow with the following properties:
+
+```
+Type: Email
+Variable name: email
+Prompt message: Please enter your email address
+Extract from history: 1
+```
+
+3. Add a third Capture Information card to the Workflow with the following properties:
+
+```
+Type: PhoneNumber
+Variable name: phone
+Prompt message: Please enter your phone number
+Extract from history: 1
+```
+
+When the user sends a message, the Workflow will begin extracting the requested information from the user's message using each Capture Information card in sequence. If a value isn't found for a particular Capture Information card, it will ask the user for the value before proceeding to the next card.
+
+You can then use the extracted variables in other parts of your Workflow, such as sending a confirmation message to the user with their captured information:
+
+```
+Thank you for submitting your information!
+We have your full name as {{workflow.fullname.first}} {{workflow.fullname.last}}, your email address as {{workflow.email}}, and your phone number as {{workflow.phone}}.
+We'll be in touch soon!
+```
+
+This will display the user's captured information in a clear and easy-to-read format for both the user and the bot.
diff --git a/src/content/docs/studio/concepts/cards/execute-code.mdx b/src/content/docs/studio/concepts/cards/execute-code.mdx
new file mode 100644
index 0000000..d6c27a4
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/execute-code.mdx
@@ -0,0 +1,47 @@
+---
+title: Execute Code
+---
+
+import { Picture } from 'astro:assets'
+import executeCodeDarkImg from './assets/execute-code-dark.png'
+import executeCodeImg from './assets/execute-code.png'
+
+import { Note, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+The Execute Code Card lets you **run custom [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) code within a Node**.
+
+You can use the Execute Code Card to extend the functionality of your bot beyond Studio's built-in Cards. For example, you can:
+
+- Perform complex calculations
+- Manipulate data and variables (see [variables in code](/studio/concepts/variables/in-code))
+- Call external APIs
+- Add guardrails such as custom error handling, rate limits, permission checks, and fallbacks
+
+
+ Execute Code Cards allow you to generate one-time code snippets at specific points in your Workflow. For reusable code
+ snippets, use [Actions](/studio/concepts/actions).
+
+
+
+
+ You can't import external libraries within an Execute Code Card. To make API requests, you can use [Axios](https://axios-http.com/docs/intro).
+
+
+
+## Generate code using AI
+
+The Execute Code card allows you to generate code using AI, so you don't have to write it all from scratch:
+
+
+
+
+
+
+At the top of the code editor, write a prompt and hit enter to generate code using AI. You can then edit this code manually or ask AI to make revisions to it.
+
+
+
+ Review AI-generated code before production. Store secrets in [configuration variables](/studio/concepts/variables/scopes/configuration) (use `env` in code), and handle slow or failed requests with `try`/`catch`, timeouts, or fallback flows.
+
+
diff --git a/src/content/docs/studio/concepts/cards/fixed-schedule.mdx b/src/content/docs/studio/concepts/cards/fixed-schedule.mdx
new file mode 100644
index 0000000..60b6cb0
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/fixed-schedule.mdx
@@ -0,0 +1,50 @@
+---
+title: Fixed Schedule
+description: Schedule a part of your Workflow.
+---
+
+import Step from '@/components/Step.astro'
+import Steps from '@/components/Steps.astro'
+import { Tip } from '@/components/callouts'
+
+The **Fixed Schedule** Card lets you trigger some part of your Workflow at a specific time.
+
+
You can use the Fixed Schedule Card to [send reminders to your users](/studio/guides/how-to/send-reminders).
+
+## Add the Card
+
+To add the Fixed Schedule Card:
+
+
+
+ Right-click anywhere in your Workflow. Then, hover over the Trigger menu:
+
+ 
+
+
+ Select **Fixed Schedule** to add the Card:
+
+ 
+
+
+
+
+## Schedule the Card
+
+You can use the Card's settings to schedule when it executes:
+
+
+
+## Set a Custom Schedule
+
+You can use a cron expression to set a custom schedule for the Card.
+
+
To learn about cron expressions and test them out yourself, check out [crontab guru](https://crontab.guru).
+
+In the Card's scheduling options, select **Custom** to open the cron field:
+
+
+
+The Card will preview when the trigger is scheduled, or let you know if your cron expression is invalid:
+
+
diff --git a/src/content/docs/studio/concepts/cards/flow-logic.mdx b/src/content/docs/studio/concepts/cards/flow-logic.mdx
new file mode 100644
index 0000000..4c48198
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/flow-logic.mdx
@@ -0,0 +1,63 @@
+---
+title: Flow Logic
+---
+
+import Accordion from '@/components/Accordion.astro'
+import AiIcon from '@/components/AiIcon.astro'
+import { Warning } from '@/components/callouts'
+
+{/* vale Botpress.workflows = NO */}
+
+Flow Logic Cards **direct the flow of your bot's conversation** based certain conditions. You can use them to guide the conversation based on user input, bot state, or external factors.
+
+There are two Flow Logic Cards available in the Card tray:
+
+## Expression
+
+The Expression Card evaluates custom expressions or conditions to make decisions within your Workflow. You can use it to transition to a Node based on a condition:
+
+- If the condition evaluates to `true`, your bot will transition to whatever Node is connected to the Expression Card
+- If the condition evaluates to `false`, your bot will skip the Card and continue its execution
+
+There are two ways to describe conditions for a transition:
+
+### Natural language
+
+You can describe the condition using natural language. In the Card's **Label** field, describe the condition, then press
Enter. This automatically updates the **Condition** field with an AI-generated [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) expression that corresponds to your condition.
+
+
+Here are some examples of conditions you could enter in the **Label** field:
+
+| Example | Description |
+| --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| User input | To check if the user entered a value between 1 and 10.
Example: _user input is between 1 & 10_ |
+| [User variable](/studio/concepts/variables/scopes/user) | To check a user variable, use **`user.{variable name}`**.
Example: _`user.language` is "English"_ |
+| [Workflow variable](/studio/concepts/variables/scopes/workflow) | To check a Workflow variable, use **`workflow.{variable name}`**.
Example: _`workflow.supportEmail` contains "Botpress"_ |
+
+
+
+### Code
+
+You can also describe the condition manually using a JavaScript expression:
+
+1. To the right of the **Condition** field, toggle
to disable generative AI for the field.
+
+2. Enter a valid JavaScript expression in the **Condition** field.
+
+## Intent
+
+
+ The Intent Card is **deprecated**—use the [AI Transition](/studio/concepts/cards/ai/ai-transition) Card instead. Any
+ existing Intent Cards in your Workflows will still work as expected.
+
+
+The **Intent** Card is used to direct the conversation's flow based on the user's recognized intent. Intents are predefined categories of user input that represent what the user wants to achieve, such as booking an appointment, asking for help, or providing feedback.
+
+When an Intent Card is triggered, it checks if the user’s input matches any of the defined intents and routes the conversation accordingly.
+
+There are two ways to define the intent you want to trigger using this card:
+
+1. By selecting a predefined intent from your Library
+2. By defining an inline intent that only exists for this card.
diff --git a/src/content/docs/studio/concepts/cards/introduction.mdx b/src/content/docs/studio/concepts/cards/introduction.mdx
new file mode 100644
index 0000000..7669e19
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/introduction.mdx
@@ -0,0 +1,69 @@
+---
+title: Cards
+sidebarTitle: Overview
+---
+
+import { Picture } from 'astro:assets'
+import cardInspectorDarkImg from './assets/card-inspector-dark.png'
+import cardInspectorImg from './assets/card-inspector.png'
+import cardsDarkImg from './assets/cards-dark.png'
+import cardsImg from './assets/cards.png'
+
+import { Tip, Note } from '@/components/callouts'
+import CardGroup from '@/components/CardGroup.astro'
+import Card from '@/components/Card.astro'
+import Frame from '@/components/Frame.astro'
+
+Cards are drag-and-drop elements that **perform tasks within a [Node](/studio/concepts/nodes/introduction)**:
+
+
+
+
+
+
+You can use Cards to:
+
+
+
+ Send text, images, and other content to users
+
+
+ Transition to another Workflow
+
+
+ Add custom JavaScript code to your Workflow
+
+
+
+This section contains documentation for all Cards in the Studio.
+
+## Add a Card
+
+1. Select **+ Add Card** on any Node to open the Card tray.
+2. Select any Card to add it to your Node.
+
+
+ Not all Cards work with every type of Node. The Card tray will only display Cards that are compatible with the Node
+ you've selected.
+
+
+
+ When you install an integration, its Cards will become available in the Card tray. Check out the [integrations
+ documentation](/integrations/get-started/introduction) for more information on integration-specific Cards.
+
+
+## Configure a Card
+
+You can access a Card's configuration options by selecting the Card after adding it to your Workflow. This will open the Card's inspector in the Studio's right panel:
+
+
+
+
+
+
+The Card's configuration fields could be either mandatory or optional—mandatory fields are marked with
\*.
+
+
+ If no Card is selected, Studio's right panel displays the [Emulator](/studio/concepts/emulator). When a Card is
+ selected, you can toggle between the **Inspector** and the **Emulator** tabs.
+
diff --git a/src/content/docs/studio/concepts/cards/send-messages.mdx b/src/content/docs/studio/concepts/cards/send-messages.mdx
new file mode 100644
index 0000000..5c8e06a
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/send-messages.mdx
@@ -0,0 +1,47 @@
+---
+title: Send Messages
+---
+
+import { Note } from '@/components/callouts'
+
+The Send Message Card lets you **send a specific message to the user**.
+
+
+ The Send Message Card is only available for [Standard Nodes](/studio/concepts/nodes/introduction#standard-node).
+
+
+## Configuration
+
+Here's a breakdown of each Send Message Card:
+
+### Text
+
+Sends a piece of text to your user. The **Message to send** field is mandatory and supports standard Markdown and variables.
+
+### Image
+
+Sends an image to your user. The **Title** field is mandatory.
+
+### Audio
+
+Sends an uploaded audio file to your user. The **Title** field is mandatory.
+
+### Video
+
+Sends an uploaded video file to your user. The **Title** field is mandatory.
+
+### File
+
+Sends a file to your user. The **Title** field is mandatory.
+
+### Card
+
+Pairs an uploaded image with a title, subtitle, and action button, like a link to a website. The **Title** and **Image** fields are both mandatory.
+
+### Carousel
+
+Groups multiple cards into a scrollable carousel.
+
+### Location
+
+Sends an address to your user. The **Latitude** and **Longitude** fields are mandatory.
diff --git a/src/content/docs/studio/concepts/cards/set-inactivity-timeout.mdx b/src/content/docs/studio/concepts/cards/set-inactivity-timeout.mdx
new file mode 100644
index 0000000..13d6909
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/set-inactivity-timeout.mdx
@@ -0,0 +1,23 @@
+---
+title: Set inactivity timeout
+---
+
+import { Tip, Note } from '@/components/callouts'
+
+You can use the Set Inactivity Timeout Card to **override the default inactivity timeout** configured in your [Bot Settings](/studio/concepts/bot-settings#inactivity-timeout).
+
+
+ This Card won't work in the Studio's Emulator. Instead, you can test it using the [shareable Webchat
+ link](/get-started/quick-start#preview-and-share-your-bot).
+
+
+## Configuration
+
+
This Card is only available for [Standard Nodes](/studio/concepts/nodes/introduction).
+
+To use the Card, just [add it to any Node in your Workflow](/studio/concepts/cards/introduction#add-a-card). The new inactivity timeout will apply starting from when the Card executes.
+
+It has the following settings:
+
+- **Conversation ID**: The ID of the conversation to update. Defaults to [`event.conversationId`](/studio/guides/advanced/event-properties#param-conversation-id) (current conversation)
+- **Timeout**: The duration of the timeout in minutes. Set to `0` for the conversation to never expire, or to `-1` to reset to the default timeout
diff --git a/src/content/docs/studio/concepts/cards/tables.mdx b/src/content/docs/studio/concepts/cards/tables.mdx
new file mode 100644
index 0000000..4cb4434
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/tables.mdx
@@ -0,0 +1,62 @@
+---
+title: Tables
+---
+
+import { Note, Warning } from '@/components/callouts'
+
+You can use table Cards to perform operations on data you have stored in a table. This page contains a list of available table Cards.
+
+
+ Table cards don't directly display their result. You'll need to first save the data in variables to be able to use
+ them in the conversation.
+
+
+## Get Record
+
+To retrieve a specific record from a table, use the **Get Record** Card. For example, you might use the Get Record operation to retrieve a user's profile information based on their unique user ID. Here's how to do it:
+
+1. Add the **Get Record** Card to the desired Node.
+2. Select the table you want to get the record from.
+3. Select the **Record ID** you want to retrieve. You can either select a default ID or use variables.
+4. Choose the result variable that will store the record data. (This variable needs be an [Object](/studio/concepts/variables/overview#data-types-for-variables) since table records are objects.)
+5. Done! You can use this variable in other Cards to access the record data.
+
+## Insert Record
+
+To create a new record in a table, use the **Insert Record** Card. This operation can be particularly useful when you need to store new information, such as a new user's details or a newly completed transaction. Here's how to do it:
+
+1. Add the **Insert Record** card to the desired Node.
+2. Select the table where you want to insert the record.
+3. Define a value for each field. You can either define a value manually or use variables.
+4. Done! Once the conversation goes through this card, the record will be created in the table.
+
+## Update Record
+
+To update a record in a table, use the **Update Record** Card. For example, you might use this operation to update a user's profile information or to update the status of a transaction. Here's how to do it:
+
+1. Add the **Update Record** card to the desired Node.
+2. Select the table you want to update.
+3. Select the **Record ID** you want to update. You can either select a default ID or use variables. For example, if you want to update a user's profile information, you can specify their user ID as the unique identifier.
+4. Select **Add properties to update**, then select the columns you want to change. For each column, you can define a value manually or use variables.
+5. Done! Once the conversation goes through this card, the record will be updated in the table.
+
+## Delete Record
+
+To delete a record in a table, use the **Delete Record** Card. For example, you might use this operation to delete a user's data if they choose to deactivate their account. Here's how to do it:
+
+1. Add the `Delete Record` card to the desired Node.
+2. Select the table where you want to delete the record.
+3. Select the ID of the record you want to delete. You can either select a default ID or use variables.
+4. Done! Once the conversation goes through this card, the record will be deleted from the table.
+
+
Deleted records can't be recovered—make sure you're deleting the correct record.
+
+## Find Records
+
+To search for and fetch multiple records, use the **Find Records** Card. For example, you might use this operation to fetch all transactions made by a specific user. Here's how to do it:
+
+1. Add the **Find Records** Card to the desired Node.
+2. Select the table where you want to find records.
+3. Define your filter criteria in natural language. You can also use variables to make this query dynamic like: `Price is below ${workflow.maxPrice}`.
+4. Choose the result variable that will store the data. (This variable needs to have the [Array](/studio/concepts/variables/overview#data-types-for-variables) type)
+5. Done! You can use this variable in subsequent Cards to access the data.
diff --git a/src/content/docs/studio/concepts/cards/utilities.mdx b/src/content/docs/studio/concepts/cards/utilities.mdx
new file mode 100644
index 0000000..efe2302
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/utilities.mdx
@@ -0,0 +1,42 @@
+---
+title: Utilities
+description: >-
+ Cards that provide utility in the Studio, and aren't part of your bot's
+ Workflow.
+---
+
+## Comment
+
+The Comment card allows you to add a comment to the Workflow. It's useful to explain the Workflow to other people or to add notes to yourself.
+
+Pick the Comment Card from the Utility Cards section in the Toolbox and drop it on the Workflow, or right-click the editor to see the Comment option. Click on the card to edit the content.
+
+You can change the text size, color and style. You can add links, pre-formatted code and bullet point lists.
+
+## Image
+
+The Image card allows you to add an image window to the Workflow. It prompts you to select a file from your local machine. The image can't be changed later.
+
+## Video
+
+The Video card allows you to add a video window to the Workflow. It accepts YouTube URLs and it's useful for adding relevant content that don't fit in notes or images. The video can't be changed later.
+
+## Log
+
+Logs a message to the Logs console and the Emulator for debugging purposes (similar to a console.log inside an execute code card), You can use it to print variables, messages or any other information you need to debug your Workflow.
+
+### Log Message
+
+The message you want to log. You can use variables and expressions.
+
+The log message can be a simple text or a JSON object. If you use a JSON object, it will be displayed in a more readable way.
+
+### Logging Levels
+
+**Debug**: Use this level to log detailed information about the Workflow execution. It's useful to debug the Workflow and understand how it works.
+
+**Info**: Use this level to log general information about the Workflow execution. It's useful to understand the Workflow behavior and the data it's processing.
+
+**Warning**: Use this level to log warnings about the Workflow execution. It's useful to alert about potential issues or unexpected behavior.
+
+**Error**: Use this level to log errors about the Workflow execution. It's useful to alert about critical issues that need to be fixed.
diff --git a/src/content/docs/studio/concepts/cards/webchat.mdx b/src/content/docs/studio/concepts/cards/webchat.mdx
new file mode 100644
index 0000000..eea446c
--- /dev/null
+++ b/src/content/docs/studio/concepts/cards/webchat.mdx
@@ -0,0 +1,32 @@
+---
+title: Webchat
+description: Cards that allow you to interact with the Webchat widget.
+---
+
+Webchat Cards are specialized Cards available in Botpress that enable you to directly control and interact with the Webchat widget embedded on your website. These Cards allow you to manage the behavior of the Webchat widget, handle user interactions, and customize the chat experience for your users.
+
+Below is an overview of each category of Webchat Interaction Cards available through the card tray:
+
+## Configure Webchat
+
+The **Configure Webchat** Card allows you to adjust the settings of the Webchat widget dynamically. You can change visual and functional aspects of the webchat, such as modifying the color scheme, adjusting welcome messages, or toggling features like file uploads. This Card helps personalize the user experience based on the context of the conversation or user preferences.
+
+## Send Custom Event
+
+The **Send Custom Event** Card is used to trigger custom events in the Webchat widget, allowing you to send data from your bot to the Webchat or perform specific actions based on user interactions. This Card is particularly useful for tracking user behavior, integrating analytics, or triggering specific Workflows within the webchat.
+
+## Get User Data
+
+The **Get User Data** Card allows you to retrieve information about the user interacting with the Webchat widget, such as their location, browser type, or other metadata. This data can be used to tailor the conversation, provide localized responses, or make decisions based on the user’s context.
+
+## Hide Webchat
+
+The **Hide Webchat** Card enables you to programmatically hide the Webchat widget from the user’s view. This can be used to control when the chat is accessible, such as hiding the widget after a session ends or when a specific condition is met.
+
+## Show Webchat
+
+The **Show Webchat** Card allows you to display the Webchat widget to the user, ensuring the chat is visible when you want to prompt user interaction. This is useful for engaging users at specific moments in their journey, such as after a certain time on the page or following a specific action.
+
+## Toggle Webchat
+
+The **Toggle Webchat** Card provides the ability to switch the Webchat widget between visible and hidden states. This Card is useful when you want to allow the user to control the visibility of the chat or when creating interactive Workflows that respond to user actions dynamically.
diff --git a/src/content/docs/studio/concepts/controls-and-settings/assets/studio-preferences.png b/src/content/docs/studio/concepts/controls-and-settings/assets/studio-preferences.png
new file mode 100644
index 0000000..e1264b9
Binary files /dev/null and b/src/content/docs/studio/concepts/controls-and-settings/assets/studio-preferences.png differ
diff --git a/src/content/docs/studio/concepts/controls-and-settings/keyboard-shortcuts.mdx b/src/content/docs/studio/concepts/controls-and-settings/keyboard-shortcuts.mdx
new file mode 100644
index 0000000..fe73058
--- /dev/null
+++ b/src/content/docs/studio/concepts/controls-and-settings/keyboard-shortcuts.mdx
@@ -0,0 +1,32 @@
+---
+title: Keyboard Shortcuts
+description: Studio Keyboard Shortcuts
+---
+
+You can use these studio shortcuts for saving your time and focusing on building better bots.
+
+| Shortcut | Windows | Mac |
+| :--------------------------------------------------- | :----------- | :----------- |
+| Copy Node | ctrl+c | cmd+c |
+| Paste Node | ctrl+v | cmd+v |
+| Delete Node | del | del |
+| Search | ctrl+f | cmd+f |
+| Toggle Left Panel
(Explorer, Library, Hooks) | ctrl+b | cmd+b |
+| Toggle Right Panel
(Inspector & Emulator) | ctrl+e | cmd+e |
+| Toggle Bottom Panel
(Debugger & logs) | ctrl+j | cmd+j |
+| Message History
(Emulator, previous messages) | Arrow ↑ or ↓ | Arrow ↑ or ↓ |
+| Create New Session
(Emulator) | ctrl+Enter | ctrl+Enter |
+
+## Admin Dashboard Keyboard Shortcuts
+
+| Shortcut | Windows | Mac |
+| :----------------------------------------------------- | :------ | :---- |
+| Access specific bots and workspaces in Admin Dashboard | ctrl+k | cmd+k |
+
+## Tables Keyboard Shortcuts
+
+| Shortcut | Windows | Mac |
+| :-------------- | :--------------------- | :--------------------- |
+| Cell Navigation | Arrow ↑ or ↓ or ← or → | Arrow ↑ or ↓ or ← or → |
+| Edit Cell | Enter | Enter |
+| Exit Edit Cell | ESC | ESC |
diff --git a/src/content/docs/studio/concepts/controls-and-settings/studio-commands.mdx b/src/content/docs/studio/concepts/controls-and-settings/studio-commands.mdx
new file mode 100644
index 0000000..f1a1581
--- /dev/null
+++ b/src/content/docs/studio/concepts/controls-and-settings/studio-commands.mdx
@@ -0,0 +1,9 @@
+---
+title: Commands
+---
+
+Botpress makes available some commands that you can use throughout your development process. These work in production as well, to troubleshoot issues and restart conversations.
+
+| Command | Where to Input | When to use |
+| :------------ | :----------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| //state/reset | In the [Emulator](/studio/concepts/emulator) or in a Channel integration | You should run this command where there's a problem with the state of your bot which could be caused by deleting nodes, Workflows or variables and other situations |
diff --git a/src/content/docs/studio/concepts/controls-and-settings/studio-preferences.mdx b/src/content/docs/studio/concepts/controls-and-settings/studio-preferences.mdx
new file mode 100644
index 0000000..00e8898
--- /dev/null
+++ b/src/content/docs/studio/concepts/controls-and-settings/studio-preferences.mdx
@@ -0,0 +1,37 @@
+---
+title: Studio Preferences
+---
+
+import { Picture } from 'astro:assets'
+import studioPreferencesImg from './assets/studio-preferences.png'
+
+
+
+## Workflow - Snap to Grid
+
+The Snap to Grid feature in Botpress allows you to align nodes and connectors on the grid, making it easier to organize and visualize your bot's Workflows.
+
+### Enabled
+
+To enable Snap to Grid, follow these steps:
+
+1. Open the Botpress Studio and navigate to the Botpress Icon (top-left)
+2. Go to **Studio Preferences** -> Check the box -> **Workflow - Snap to Grid**.
+
+Once Snap to Grid is enabled, the nodes and connectors will automatically align to the nearest grid lines when they're moved.
+
+### Disabled
+
+When the **Snap to Grid** feature is turned off, the Workflow editor allows for more free-form movement of nodes and connections. Nodes and connections can be dragged and placed anywhere on the canvas, without being automatically aligned to the grid.
+
+This can be useful for creating more complex and visually dynamic Workflows that don't conform to a strict grid layout.
+
+## Studio Theme
+
+The Studio Theme feature allows you to change the color scheme of the Botpress Studio interface. This can be useful for customizing the look and feel of your bot, or for making it easier to distinguish between different bots in your workspace.
+
+Available themes include:
+
+1. System (default)
+2. Light
+3. Dark
diff --git a/src/content/docs/studio/concepts/copy-to-bot.mdx b/src/content/docs/studio/concepts/copy-to-bot.mdx
new file mode 100644
index 0000000..8963e91
--- /dev/null
+++ b/src/content/docs/studio/concepts/copy-to-bot.mdx
@@ -0,0 +1,62 @@
+---
+title: Copy to bot
+description: Duplicate the configuration of a bot into another bot.
+icon: Copy
+---
+
+import { Picture } from 'astro:assets'
+import copyToBotImg from './assets/copy-to-bot.png'
+
+### Use Cases
+
+This feature is useful in couple scenarios:
+
+**Development, Staging, and Production Environments**:
+
+- Maintain separate bots for development, staging, and production. This allows you to experiment freely in the development bot and test changes without compromising the settings or data of your staging or production bots.
+
+**Managing Multiple Client Bots:**
+
+- If you maintain a single master bot and deploy multiple copies as production bots for different clients, this feature helps keep them synchronized while ensuring each remains isolated.
+
+---
+
+### How to Copy a Bot
+
+1. In **Botpress Studio**, navigate to the left panel and click the **Botpress icon**.
+2. Hover over **Copy to Bot** and select the bot you want to copy to (or create a new bot).
+3. A confirmation dialog will appear, warning that this action will modify the target bot. Click **Confirm** to proceed.
+4. The copy process will begin. Once complete, a dialog will appear with details about the updates made to the target bot.
+5. From here, you can choose to open the target bot or close the dialog and continue editing the source bot.
+
+
+
+---
+
+### How it works
+
+When a user requests to copy a bot to another bot, the following actions are performed:
+
+**Workflows, Variables and Hooks are copied**
+
+- All Workflows, variables and hooks from the source bot will be copied to the target bot.
+- Existing Workflows and variables in the target bot will be overwritten.
+
+**Integrations are synced**
+
+- New or outdated integrations from the source bot will be installed in the target bot. These will need to be configured in the target bot’s studio.
+- Existing integrations in the target bot will be preserved with their configuration.
+- Integrations that exist only in the target bot will remain unchanged.
+
+**Tables are synced**
+
+- New tables from the source bot will be added to the target bot.
+- New columns in existing tables will be added to the corresponding tables in the target bot. If there was existing data, the new column will be null for each entry.
+- Deleted columns in existing tables will be removed from the target bot’s equivalent tables. If there was existing data, only the data for that column will be lost—other data remains intact.
+- Tables that exist only in the target bot will remain unchanged.
+
+**Knowledge Base (KB) Files are synced**
+
+- New files from the source bot will be duplicated in the target bot.
+- If a file is updated in the source bot, the corresponding file in the target bot will be overwritten.
+- Files that exist only in the target bot will remain unchanged.
diff --git a/src/content/docs/studio/concepts/debugger-logs-json.mdx b/src/content/docs/studio/concepts/debugger-logs-json.mdx
new file mode 100644
index 0000000..c70a6b6
--- /dev/null
+++ b/src/content/docs/studio/concepts/debugger-logs-json.mdx
@@ -0,0 +1,108 @@
+---
+title: Debugger, Logs & JSON
+icon: Logs
+---
+
+import { Picture } from 'astro:assets'
+import eventDebuggerLogsJsonImg from './assets/event-debugger-logs-json.png'
+
+import { Note } from '@/components/callouts'
+
+
+
+## Event Debugger
+
+The Event Debugger provides information on how your bot understood the user's message and why it made specific decisions. It also displays the complete event payload, including NLU metadata, state, and raw responses.
+
+To open or close the Debugger, you can use the keyboard shortcut **cmd/ctrl + j**. This will toggle the Debugger on and off and allow you to access the information it provides.
+
+## Logs
+
+By using logs, you can see what happened step-by-step before an error occurred. This can help you understand what went wrong and how to fix it.
+
+It's important to include enough logging in your bot to ensure that you have enough\
+information to find and fix issues. By analyzing the Botpress Logs, you can pinpoint\
+exactly where the problem occurred and take the necessary steps to resolve it.
+
+Logging in Botpress is similar to logging in JavaScript. You can use the `console.log()` function in the [Code Card](/studio/concepts/cards/execute-code) to print messages to the Botpress Logs. This function takes a string as an argument and prints it to the Botpress Logs.
+
+### Logging User Information
+
+If you're interested in understanding what user data is being processed, you might want to log their first name. This could help you trace if the correct user data is being accessed and used in your Workflow.
+
+**Example use-case**: Understanding which user's data is being processed especially if your bot offers personalized experiences.
+
+```javascript
+console.log("User's First Name:", user.firstName)
+```
+
+### Logging Workflow Data
+
+You might want to know which phone number is being used in a specific Workflow. By logging this, you can ensure that the correct numbers are being pulled from your database or user input.
+
+**Example use-case**: Debugging Workflows that might involve sending SMS messages or making phone calls. Ensuring that the correct phone numbers are used can be critical.
+
+```javascript
+console.log('Workflow Phone Number:', workflow.phoneNumber)
+```
+
+### Logging Environment Configurations
+
+If your bot accesses external APIs or databases, the API key or endpoint might change depending on the environment (development, staging, production, etc.). Logging the `env` variables can help ensure that the bot is using the correct configurations.
+
+**Example use-case**: Troubleshooting connectivity or access issues with external services. By logging the API key or endpoint, you can ensure you're using the correct configurations and not accidentally hitting a production database during development or vice versa.
+
+```javascript
+console.log('Current API Key:', env.apiKey)
+```
+
+### Checking the Botpress Studio Logs
+
+To check the Botpress Studio Logs, open up the bottom panel and click on the **Logs** tab. This will display all the logs that have been generated by your bot.
+
+
+Note
+
+The logs are displayed in reverse chronological order, with the most recent log at the top. You can click on a log to expand it and view its details.
+
+
+
+### Checking the Production Logs
+
+To check the [Production Logs](/get-started/manage-your-agent/inspect#logs) (or logs from a deployed bot), go to the admin dashboard -> select your workspace and bot -> click on the **Logs** tab. This will display all the logs that have been generated by your deployed bot.
+
+## State
+
+In a bot conversation, each session has an associated state which is created at the beginning of the conversation just before the Entry Node is processed. The state persists throughout the conversation and is used to keep track of information related to the ongoing interaction with the user.
+
+The state is global to the conversation, which means that if the conversation spans multiple Workflows, all the Workflows will share the same state. This allows information to be passed between Workflows and ensures that the bot has a consistent view of the conversation history.
+
+The state can be used to store variables, such as the user's name, preferences, or history of interactions, that are needed throughout the conversation. It can also be used to keep track of the bot's progress through the conversation, such as which questions have been asked and which tasks have been completed.
+
+By using the state effectively, you can create more personalized and engaging bot experiences for your users.
+
+## JSON
+
+This tab displays the raw information that's processed during each conversation exchange in the Botpress Emulator. The information can be accessed through **event.property**, where "property" refers to one of the properties listed in the table below.
+
+Here is a table that describes each property in detail:
+
+| Property | Description |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Type | A string property that indicates the type of the message (text, audio, video, etc.) |
+| Channel | A string property that specifies the channel or platform through which the message was received. For example, the channel can be an emulator, Facebook Messenger, WhatsApp, etc. |
+| Direction | A string property that specifies the direction of the message-whether the message is incoming or outgoing. |
+| Payload | A JSON object that encapsulates the message data. The structure of the payload object depends on the type of message. |
+| UserId | A string property that identifies the user who sent the message. |
+| BotId | A string property that identifies the bot or conversational AI system that received the message. |
+| CreatedOn | A timestamp that specifies the date and time when the message was received. |
+| ConversationId | A string property that identifies the conversation thread to which the message belongs. |
+| ID | A unique identifier for the message. |
+| Preview | A preview or summary of the message. |
+| MessageId | A string property that identifies the ID of the message. |
+| Tags | An object that contains tags associated with the message. |
+| Flags | An object that contains flags associated with the message. |
+| State | An object that contains the state of the conversation. |
+| Suggestions | An array of suggested responses or actions that the bot can take based on the message. |
+| NLU | An object that encapsulates the results of the natural language understanding (NLU) process for the message. |
+| Decision | An object that encapsulates the decision-making process for the message. |
diff --git a/src/content/docs/studio/concepts/emulator.mdx b/src/content/docs/studio/concepts/emulator.mdx
new file mode 100644
index 0000000..87cffae
--- /dev/null
+++ b/src/content/docs/studio/concepts/emulator.mdx
@@ -0,0 +1,90 @@
+---
+title: Emulator
+icon: MessagesSquare
+---
+
+import { Note, Info } from '@/components/callouts'
+
+You can debug your bot conversation using the built-in Emulator in the right-side panel.
+
+
+Note
+
+To visualize the actual user experience, use the Share button to have a hosted easily shareable version of the [Web Chat](/webchat/get-started/introduction) (this is the production bot already, conversations will be saved) or ideally test the bot in the channel you intend to deploy it on. Conversations in the Emulator won't be saved and the [bot invocations](/get-started/configure-your-workspace#track-usage-quotas) won't be counted against your usage quota, but AI operations will.
+
+
+
+## Shortcuts
+
+### Accessing the Emulator
+
+Press `cmd/ctrl + e` to toggle the Emulator open or closed.
+
+### Resend the Same Messages
+
+Pressing ↑ or ↓ on your keyboard in the text input allows you to navigate and resend previously sent messages quickly.
+
+
+Info
+
+The last 20 messages sent are persistently stored in your browser storage.
+
+
+
+## Options
+
+### New Conversation
+
+The `New Conversation` button erases the history and state from the old conversation and start a new conversation with the same user information. It's available at the top right corner of the emulator.
+
+### Start as a new user
+
+The `Start as new user` button erases the history and state from the old conversation and start a new conversation with different user information. It's available at the top right corner of the emulator behind the 3 dots.
+
+### Simulate timeout event
+
+The `Simulate timeout event` button triggers the [Timeout Workflow](/studio/concepts/workflows#timeout) so you can check how the bot behaves when the conversation expires. It's available at the top right corner of the emulator behind the 3 dots.
+
+## In-line Logs
+
+The Emulator shows the status of the conversation and the different steps that are being or have been executed under the hood to get the bot's response. They're a simpler version of the [Event Debugger](/studio/concepts/debugger-logs-json)'s summary. Bot events, and card-processing results are shown this way, only in the emulator.
+
+### Bot events
+
+- Conversation started: The user has started the conversation by sending a message or a [Trigger](/studio/concepts/triggers) has fired.
+- Conversation ended: The conversation flowed to an End node and has gone through the [Conversation End Workflow](/studio/concepts/workflows#conversation-end), or it has ended by not having possible transitions.
+- Error occurred: An irrecoverable error has occurred and the conversation has flowed to the [Error](/studio/concepts/workflows#error) . The error message is visible by hovering the status.
+- Waiting for user input: The bot is waiting for the user to send a message in order to proceed with the conversation.
+
+### Knowledge Base
+
+- Answer found in Knowledge Base: The bot has gone through the [Knowledge Bases](/studio/concepts/knowledge-base/introduction) and found an answer to the user's question. Clicking it will take you to the [Logs tab](/studio/concepts/debugger-logs-json) where you can see in details what was sent to the AI and the raw output.
+- Knowledge disabled on that node: The bot won't try to find an answer in the Knowledge Base because this node doesn't expect or accept Knowledge questions.
+- No content matched the query: There is no content in the Knowledge Base that matches the user message. May accompany the previous status.
+- Knowledge Base answer: Text displayed automatically after a question without the need of a Text card. It will contain the citations to help you [debug the answers](/studio/concepts/knowledge-base/introduction#debugging).
+
+### Execute
+
+- Executing code: The bot is executing some custom code from an [Execute Code card](/studio/concepts/cards/execute-code).
+- Executed code: The bot has finished executing the code. It's mentioned how many milliseconds it took to run.
+
+### AI
+
+- AI Task Running: The bot is running an AI Task. This involves making a request to the selected LLM model, getting a response and then processing it.
+- AI Task Completed: The bot has finished running the AI Task. It's mentioned how many milliseconds it took to run.
+
+{/* vale Botpress.workflows = NO */}
+
+### Flow Logic
+
+{/* vale Botpress.workflows = YES */}
+
+- Entered Workflow - The conversation has flowed to a different Workflow. The Workflow name is mentioned.
+- Transitioned: The conversation has flowed to another Workflow or node. It's mentioned the name of the Workflow and the node it transitioned to. Clicking it will lead you to the exact node.
+- Restarting from node: The conversation is being restarted from a specific node by user request. It's mentioned the name of the node it's restarting from.
+
+### Capture Information
+
+- Capturing Variable: The bot is currently trying to extract information from the user message with a [Capture card](/studio/concepts/cards/capture-information) to optionally save it in a [variable](/studio/concepts/variables/overview).
+- Captured variable: The bot has successfully extracted information from the user message and saved it in a variable.
+- Capture variable failed: The bot wasn't able to extract information and has reached the limit of [retries](/studio/concepts/cards/capture-information#retries).
diff --git a/src/content/docs/studio/concepts/find.mdx b/src/content/docs/studio/concepts/find.mdx
new file mode 100644
index 0000000..d1deddc
--- /dev/null
+++ b/src/content/docs/studio/concepts/find.mdx
@@ -0,0 +1,14 @@
+---
+title: Find
+description: Quickly search through your bot's content, Workflows, and configurations.
+icon: Search
+---
+
+The Find function in Botpress Studio is a powerful tool that helps you quickly search through your bot’s content, Workflows, and configurations. It allows you to locate specific elements, such as nodes, actions, text, or variables, within your bot project, making it easier to navigate and edit complex bots.
+
+## Features
+
+- **Quick Search:** Instantly locate items like specific nodes, cards. actions, intents, or text within your Workflows and content.
+- **Contextual Results:** Provides contextual search results, showing where the found items are located within the bot’s structure.
+- **Navigation:** Click on a search result to jump directly to that element within the Botpress Studio.
+- **Keyword Highlighting:** Highlights occurrences of your search term in the Workflows, helping you see exactly where changes are needed.
diff --git a/src/content/docs/studio/concepts/home.mdx b/src/content/docs/studio/concepts/home.mdx
new file mode 100644
index 0000000..95a7684
--- /dev/null
+++ b/src/content/docs/studio/concepts/home.mdx
@@ -0,0 +1,119 @@
+---
+title: Home
+description: >-
+ Main menu with global configuration for your bot.
+icon: House
+---
+
+import { Picture } from 'astro:assets'
+import commChannelsDarkImg from './assets/comm-channels-dark.png'
+import commChannelsImg from './assets/comm-channels.png'
+import homeInstructionsDarkImg from './assets/home-instructions-dark.png'
+import homeInstructionsImg from './assets/home-instructions.png'
+import knowledgeBaseDarkImg from './assets/knowledge-base-dark.png'
+import knowledgeBaseImg from './assets/knowledge-base.png'
+import learningExperiencesDarkImg from './assets/learning-experiences-dark.png'
+import learningExperiencesImg from './assets/learning-experiences.png'
+import nodeCardsDarkImg from './assets/node-cards-dark.png'
+import nodeCardsImg from './assets/node-cards.png'
+import nodeInstructionsDarkImg from './assets/node-instructions-dark.png'
+import nodeInstructionsImg from './assets/node-instructions.png'
+import toolsDarkImg from './assets/tools-dark.png'
+import toolsImg from './assets/tools.png'
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+The
**Home** page is Botpress Studio's main menu. It displays general information about your bot and allows you to configure some global settings.
+
+Most of the options on the **Home** page are shortcuts to configure your main Workflow's [Autonomous Node](/studio/concepts/nodes/autonomous-node). If you don't use an Autonomous Node, you can still configure your bot's [communication channels](#communication-channels) or view a [detailed analysis of your bot's conversations](#conversation-analysis).
+
+## Instructions
+
+
+ The **Instructions** field is only available if you have an [Autonomous Node](/studio/concepts/nodes/autonomous-node)
+ in your bot's main Workflow.
+
+
+You can define a global prompt for your bot in the **Instructions** field. This prompt influences how the bot interprets and responds to user input by giving it a specific context or role to operate within:
+
+
+
+
+
+
+The **Instructions** field directly maps to the **Instructions** for your main Workflow's Autonomous Node. When you update one, the other will also update:
+
+
+
+
+
+
+## Knowledge Bases
+
+
+ The **Knowledge Base** section is only available if you have an [Autonomous
+ Node](/studio/concepts/nodes/autonomous-node) in your bot's main Workflow.
+
+
+You can add [Knowledge Bases](/studio/concepts/knowledge-base/introduction) to give your bot sources it can reference when answering questions:
+
+
+
+
+
+
+These sources can include documents, websites, tables, and other forms of structured (or unstructured) data. When you add Knowledge Bases, this section will display a summary of them.
+
+## Tools
+
+
+ The **Tools** section is only available if you have an [Autonomous Node](/studio/concepts/nodes/autonomous-node) in
+ your bot's main Workflow.
+
+
+You can use the **Tools** section to quickly add resources and actions your bot can use:
+
+
+
+
+
+
+The **Tools** section directly maps to the Cards in your main Workflow's Autonomous Node. When you update one, the other will also update:
+
+
+
+
+
+
+## Communication Channels
+
+
+ For detailed guides on setting up different channels, check out the [Integrations documentation](/integrations/).
+
+
+You can deploy your bot in different channels the **Communication Channels** section:
+
+
+
+
+
+
+## Conversation analysis
+
+You can view a summary of your bot's conversations in the **Conversation Analysis** section. This includes sentiment analysis, summaries of conversation topics, and insights into whether users' questions were resolved.
+
+## Learning Experiences
+
+
+ The **Learning Experiences** section is only available if you have an [Autonomous
+ Node](/studio/concepts/nodes/autonomous-node) in your bot's main Workflow.
+
+
+You can provide feedback on your bot's responses in the [Emulator](/studio/concepts/emulator). Then, you can view a summary of your feedback in the **Learning Experiences** section:
+
+
+
+
+
diff --git a/src/content/docs/studio/concepts/hooks.mdx b/src/content/docs/studio/concepts/hooks.mdx
new file mode 100644
index 0000000..8702a2b
--- /dev/null
+++ b/src/content/docs/studio/concepts/hooks.mdx
@@ -0,0 +1,305 @@
+---
+title: Hooks
+icon: Anchor
+---
+
+import Expandable from '@/components/Expandable.astro'
+import { Field } from '@/components/field'
+import IncomingEvent from '@/components/IncomingEvent.astro'
+import { Tip, Note } from '@/components/callouts'
+import Icon from '@/components/Icon.astro'
+
+Hooks **execute custom JavaScript code** at specific cycles of your bot's operation. For example:
+
+- [Before each outgoing message](#before-outgoing)
+- [After each LLMz iteration](#after-llmz-iteration)
+- [At the end of each conversation](#after-conversation-end)
+
+You can use Hooks to intercept and modify messages, perform logging, integrate with external systems, and more.
+
+
+### Hooks vs. Actions / Execute Code
+
+Hooks let you use custom code with your bot, just like [Actions](/studio/concepts/actions) and [Execute Code Cards](/studio/concepts/cards/execute-code). The key difference is when the code runs: - Actions and Execute Code Cards run at some point in your [Workflow](/studio/concepts/workflows). - Hooks run during specific stages of the bot’s operation cycle
+
+
+
+## Overview
+
+When you add a new Hook, it defines a [function](https://www.w3schools.com/js/js_functions.asp) that executes every time your bot reaches a certain cycle of its operation.
+
+All Hooks take an `event` parameter, which contains information about the event that triggered the Hook.
+
+
Some Hook types take additional parameters—check out the Hook guides on this page for more information.
+
+### Add a Hook
+
+1. Navigate to the
Hooks section in the Studio's left navigation bar.
+2. Select **Create Hook**, then choose a type for the Hook.
+3. Choose a name for the Hook. Done!
+
+---
+
+## Hook types
+
+Here's a breakdown of each type of Hook:
+
+### Before Incoming
+
+This Hook type executes its code before your bot processes an incoming `event`.
+
+**Parameters**:
+
+
+
+### After Incoming
+
+This Hook type executes its code after the incoming message has been processed, but before the bot has responded.
+
+**Parameters**:
+
+
+
+### Before Outgoing
+
+This Hook type executes its code before the bot's reply is sent to the user.
+
+**Parameters**:
+
+
+
+ The message sent by the bot
+
+
+### Before LLMz Execution
+
+This Hook type executes its code before the LLMz engine begins its execution.
+
+**Parameters**:
+
+
+
+ The current context provided to the LLMz
+
+
+
+
+ The unique identifier of the LLMz execution, prefixed with `llmz_`
+
+
+
+ The version of the LLMz engine or context
+
+
+
+ Optional instructions provided to guide the LLMz execution
+
+
+
+ A list of objects relevant to the LLMz context
+
+
+
+ A list of tools available for the LLMz engine to use
+
+
+
+ The current loop count of the LLMz iteration process
+
+
+
+ The temperature setting used for the LLM model
+
+
+
+ The name or identifier of the LLM model being used.
+
+
+
+ The conversation transcript, including all prior messages in the current context
+
+
+
+ The current location within the bot's logic
+
+
+
+
+
+### After LLMz Execution
+
+This Hook type executes its code after the LLMz engine finishes its execution.
+
+**Parameters**:
+
+
+
+ The result of the execution
+
+
+### After LLMz iteration
+
+Depending on how demanding the task is, the LLMz may loop through multiple iterations before finishing its execution. This Hook type executes its code after each iteration.
+
+**Parameters**:
+
+
+
+ The result of the iteration
+
+
+### After Conversation End
+
+This Hook type executes after the conversation has **explicitly ended** (transitioned to an [End Node](/studio/concepts/nodes/introduction#end-node))
+
+**Parameters**:
+
+
+
+### After Turn End
+
+This Hook type executes after a full turn has completed—meaning the bot has received user input, processed it, and responded.
+
+You can use a Hook of this type to [track AI spend and token cost](/studio/guides/how-to/track-ai-spend-in-table/) for your bot.
+
+**Parameters**:
+
+
+
+ The turn's metadata
+
+
+
+ The token information and cost for the current turn
+
+
+
+ A summary of the token usage for the last turn
+
+
+ A detailed breakdown of token usage for the last turn
+
+
+ The number of billed tokens during the last turn
+
+
+ An array of token usages
+
+
+
+ The number of tokens in the usage
+
+
+ The AI spend for the usage (in nanodollars). To get the number in dollars, divide this number by 1,000,000,000.
+
+
+ The duration (in milliseconds) of the usage
+
+
+ The location in the Workflow where the usage occurred
+
+
+ Whether the usage was cached
+
+
+
+
+ The total number of tokens used in the last turn
+
+
+ The total number of billed tokens used in the last turn
+
+
+ The AI spend for the last turn (in nanodollars). To get the number in dollars, divide this number by 1,000,000,000.
+
+
+ The percentage of savings on AI spend for this turn.
+
+
+
+
+
+
+
+## Troubleshooting
+
+If your Hook isn't behaving as expected, you can [check your bot's logs](/studio/concepts/debugger-logs-json) to diagnose any problems.
diff --git a/src/content/docs/studio/concepts/import-export-bots.mdx b/src/content/docs/studio/concepts/import-export-bots.mdx
new file mode 100644
index 0000000..da860d2
--- /dev/null
+++ b/src/content/docs/studio/concepts/import-export-bots.mdx
@@ -0,0 +1,86 @@
+---
+title: Import & Export
+icon: FolderSync
+---
+
+import YouTube from '@/components/YouTube.astro'
+import { Tip, Note, Info, Warning } from '@/components/callouts'
+
+You may want to import or export a bot for various reasons, such as:
+
+- Sharing the bot with others - friends, clients, etc.
+- Contributing the bot to the community
+- Seeking help to fix issues
+- Creating a backup of the bot
+- Transferring the bot to a different workspace or account
+
+And with Botpress Cloud, you can do that with just a few clicks!
+
+## How to Export a Bot
+
+On the left panel in your Botpress Studio, click the Botpress icon and select Import / Export. Then click Export as.
+
+Studio will start preparing the export, which may take some time, depending on the amount of content in your tables and knowledge bases. When it's done, the download will start automatically.
+
+
+Info
+
+Bots \~3gb or larger **can't** be exported!
+
+
+
+The exported file will be a `.bpz` file (which is a special archive format for Botpress Cloud bots). It will have the name of your bot and the current date (for example: recipe-bot - 2023 Sep 06.bpz).
+
+
+Warning
+
+Don't attempt to extract the file or modify its content; otherwise, you may not be able to import your bot again!
+
+
+
+The exported file contains your whole bot, including:
+
+- Bot information and settings
+- Agents settings
+- Knowledge bases - with sources (files are stored on our servers and only linked in the export to keep it small)
+- Tables - with records
+- Intents and entities
+- Hooks
+- Variables (Workflow, user, bot, configuration) - names and default values
+- Folders
+- Workflows and nodes
+- Cards - with content
+- Transition lines
+
+So you can rest assured that all of your data is included!
+
+## How to Import a Bot
+
+
+Warning
+
+Importing a bot will overwrite the current bot, including media, knowledge bases, documents and tables. Proceed with caution!
+
+
+
+On the left panel in your Botpress Studio, click the Botpress icon and select Import / Export. Then click Import. Next, click "Select bot archive to upload" and the explorer window will open. Find the `.bpz` file you want to import on your computer and click Open.
+
+You have now successfully imported your bot! Test it using the Emulator or publish it to make it available to your users.
+
+
+Good to know
+
+You can import bots up to 120 MB!
+
+
+
+
+Restoring the Integrations
+
+Remember to set up the desired integrations again in the Dashboard, so that it works on the channels exactly as it did before you exported it!
+
+
+
+## Video tutorial
+
+
diff --git a/src/content/docs/studio/concepts/inspector.mdx b/src/content/docs/studio/concepts/inspector.mdx
new file mode 100644
index 0000000..49552df
--- /dev/null
+++ b/src/content/docs/studio/concepts/inspector.mdx
@@ -0,0 +1,28 @@
+---
+title: Inspector
+excerpt: ''
+deprecated: false
+hidden: true
+metadata:
+ title: ''
+ description: ''
+ robots: index
+next:
+ description: ''
+---
+
+The top right-hand side panel is the Inspector. The Inspector will display additional properties of the components you select in the main (center) panel.
+
+## Logged-in Account
+
+Shows the Account that you've logged in. Click on it to log-out.
+
+## Share
+
+Click on the Share button to share your bot with others. You can share your bot with others by sending them the link to your bot.
+
+Make sure to hit the Publish button first to make your bot publicly available.
+
+## Publish
+
+Your bot will only be made publicly available (or updated) when you publish it with this one-click deployment to the cloud.
diff --git a/src/content/docs/studio/concepts/integrations.mdx b/src/content/docs/studio/concepts/integrations.mdx
new file mode 100644
index 0000000..89cf6ef
--- /dev/null
+++ b/src/content/docs/studio/concepts/integrations.mdx
@@ -0,0 +1,40 @@
+---
+title: Integrations
+description: Allow your bot to connect to external services, APIs, and tools.
+icon: Plug
+---
+
+import { Check } from '@/components/callouts'
+
+Integrations extend the capabilities of your bots by connecting them with external services, APIs, and tools. They allow your bots to fetch data, trigger actions, interact with third-party platforms, and provide more dynamic and powerful user experiences. They can send and receive data from other tools, or they can be used to deploy your bot on alternative messaging channels.
+
+## Using Integrations
+
+### Search
+
+To find integrations, navigate to the integrations icon in the left-hand menu of the Studio, indicated by a puzzle icon.
+
+You can search for integrations to third-party services by name here, like WhatsApp or Messenger.
+
+### Install
+
+Clicking on an integration from a search result will open a menu that allows you to install that integration to your bot. From this menu, you can also see information like prerequisites, installation instructions, and the Botpress user responsible for contributing the integration to the hub.
+
+
+Verification
+
+Integrations with a checkmark icon next to the name have been verified and confirmed as trusted integrations for safety and function by the Botpress team.
+
+
+
+### Configure
+
+Once you've installed an integration to your bot, you can proceed with any necessary configuration steps. This can include providing API keys, inputting data, or completing third-party setup wizards.
+
+### Usage
+
+Once you've installed and configured an integration to your bot, you can start using it.
+
+For integrations that deploy your bot to a messaging channel like WhatsApp or Telegram, after you've configured the integration and published your bot, it will start sending and receiving messages on those channels.
+
+For integrations that enhance your bot's functionalities, like connecting to a third-party tool, you will find additional cards in the Card Tray that enable certain integration actions. Refer to the documentation for the integration you are using for detailed instructions.
diff --git a/src/content/docs/studio/concepts/knowledge-base/add-sources.mdx b/src/content/docs/studio/concepts/knowledge-base/add-sources.mdx
new file mode 100644
index 0000000..7601e4d
--- /dev/null
+++ b/src/content/docs/studio/concepts/knowledge-base/add-sources.mdx
@@ -0,0 +1,139 @@
+---
+title: Add sources to Knowledge Base
+sidebarTitle: Add sources
+---
+
+import { Note } from '@/components/callouts'
+
+You can add sources to a Knowledge Base—your bot will reference them when searching for an answer to a user's question.
+
+---
+
+## Websites
+
+To add a website to your Knowledge Base, select **Website** in its menu. Here's a breakdown of the options for adding websites:
+
+### From a website's root domain
+
+By default, you can add a root domain (or some subpath of a root domain) and let Botpress discover the other pages on that website.
+
+For example, if you enter `botpress.com`, Botpress will discoverer all the subpaths of that domain, like:
+
+- `botpress.com/docs`
+- `botpress.com/features/knowledge-bases`
+- `botpress.com/industries/ecommerce`
+
+and more. Then, you can select which pages to add to your Knowledge Base.
+
+### From specific pages
+
+If you want to add specific web pages without discovering any subpaths, open the drop-down menu and select **Specific Web Pages**. Then, enter the exact address of the page you want to add.
+
+For example, if you enter `botpress.com/blog`. you'll add that exact page only—none of its subpaths will be included.
+
+### Re-crawling
+
+By default, Botpress indexes any web pages you add once, then continues to reference that version of the pages. However, you can also schedule a re-crawling of the pages:
+
+1. After adding web pages to your Knowledge Base, select them from your list of knowledge sources.
+2. Open the **Recrawl** drop-down menu.
+3. Select one of the other re-crawling schedules—like **Recrawl Daily**.
+
+Re-crawling is useful for keeping your bot up to date on changes to your website. For example, the Botpress documentation's
+
+
window.botpress.open()}>AI assistant
+re-crawls `botpress.com/docs` every day to stay up-to-date when new documentation is added.
+
+---
+
+## Documents
+
+You can upload documents and files to your Knowledge Base—just select the **Documents** option from its menu. Here's a list of supported file formats:
+
+- `.pdf`
+- `.html`
+- `.txt`
+- `.doc`
+- `.docx`
+- `.md`
+
+
Documents can be up to 50 MB each.
+
+### From API
+
+Knowledge Bases use the Botpress [Files API](/api-reference/files-api/getting-started) to manage documents. This means you can programmatically upload documents to a Knowledge Base:
+
+1. Select the **API** option from your Knowledge Base's menu.
+2. Follow the on-screen instructions.
+
+---
+
+## Tables
+
+If you use [tables](/studio/concepts/tables) to store data, you can connect them to a Knowledge Base.
+
+1. Open the Knowledge Base.
+2. Select the **Table** option.
+3. Select any tables you'd like to add.
+
+After adding a table to your Knowledge Base, users can ask natural-language questions about the data in your tables—this is useful for inventory data, pricing charts, and other types of structured data.
+
+---
+
+## Search the web
+
+You can give your bot the ability to search the web independently for answers to user questions—just select **Web Search** from your Knowledge Base's menu.
+
+While [adding websites](#add-websites) indexes data from specific web pages for your bot to reference, the **Web Search** searches the internet in real time to find an answer to the user's prompt.
+
+By default, this option gives your bot access to search the entire web. However, you can also filter the results:
+
+### Filter by website
+
+You can filter which websites your bot searches on. Under **On which websites should we search on**, open the drop-down menu :
+
+- **Search on specific websites**: Useful for scoping responses to specific sources, like a company website.
+- **Search the entire web**: Useful when your bot needs access to a broader set of information to answer user questions.
+- **The entire web, except these websites**: Useful for filtering out unreliable sources or competitors' websites
+
+### Filter by time period
+
+You can filter search results by time period. Under **Filter search results by time period**, open the drop-down menu:
+
+- **Don't filter based on time**
+- **Pages discovered in the last 24 hours**
+- **Pages discovered in the last 7 days**
+- **Pages discovered in the last 30 days**
+
+When you select one of these options, it'll only include pages that Botpress indexed or discovered in the specified range.
+
+---
+
+## Rich text
+
+You can add rich text directly into a Knowledge Base.
+
+1. Open the Knowledge Base.
+2. Select the **Rich Text** option.
+
+By default, this adds an empty rich text document—you can then open and edit its contents.
+
+### Filter by column
+
+By default, all your table's columns are available in the Knowledge Base. If you want to filter results to only specific columns, select the table and uncheck any columns you want to exclude.
+
+
+ If your table is displaying **No searchable columns**, make sure your table has at least one column [marked as
+ searchable](/studio/concepts/tables#making-fields-searchable).
+
+
+You can connect your tables of data to a Knowledge Base, allowing users to directly search for information. This can be especially invaluable for vast datasets, as it provides a straightforward and user-friendly method to retrieve data.
+
+---
+
+## Sources from integrations
+
+You can add content from certain [integrations](/integrations/get-started/introduction) to your Knowledge Base. If you install an integration that's compatible with Knowledge Bases, that integration will either:
+
+- Be displayed alongside the other options in your Knowledge Base (like the [Notion](https://botpress.com/integrations/notion) integration)
+- Have [Cards](/studio/concepts/cards/introduction) that handle synchronization with Knowledge Bases (like the [Google Drive](https://botpress.com/integrations/googledrive) integration)
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy-dark.png b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy-dark.png
new file mode 100644
index 0000000..8696f96
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy-dark.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy.png b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy.png
new file mode 100644
index 0000000..247f037
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-policy.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing-dark.png b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing-dark.png
new file mode 100644
index 0000000..e2fd4f1
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing-dark.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing.png b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing.png
new file mode 100644
index 0000000..3b56a44
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/example-instructions-pricing.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base-dark.png b/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base-dark.png
new file mode 100644
index 0000000..b73dc86
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base-dark.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base.png b/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base.png
new file mode 100644
index 0000000..ed8ef2a
Binary files /dev/null and b/src/content/docs/studio/concepts/knowledge-base/assets/knowledge-base.png differ
diff --git a/src/content/docs/studio/concepts/knowledge-base/introduction.mdx b/src/content/docs/studio/concepts/knowledge-base/introduction.mdx
new file mode 100644
index 0000000..7dd323d
--- /dev/null
+++ b/src/content/docs/studio/concepts/knowledge-base/introduction.mdx
@@ -0,0 +1,228 @@
+---
+title: Knowledge Bases
+sidebarTitle: Overview
+---
+
+import { Picture } from 'astro:assets'
+import exampleInstructionsPolicyDarkImg from './assets/example-instructions-policy-dark.png'
+import exampleInstructionsPolicyImg from './assets/example-instructions-policy.png'
+import exampleInstructionsPricingDarkImg from './assets/example-instructions-pricing-dark.png'
+import exampleInstructionsPricingImg from './assets/example-instructions-pricing.png'
+import knowledgeBaseDarkImg from './assets/knowledge-base-dark.png'
+import knowledgeBaseImg from './assets/knowledge-base.png'
+
+import { Tip, Note, Warning } from '@/components/callouts'
+import CardGroup from '@/components/CardGroup.astro'
+import Card from '@/components/Card.astro'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+
Knowledge Bases are **sources of information you provide to your bot**.
+
+
+
+
+
+
+You can use a Knowledge Base to make your bot reference a specific source when answering a user. For example, you might want to:
+
+- Provide your bot with specialized information (like company policies, pricing charts, or troubleshooting steps)
+- Scope your bot's responses to specific topics
+- Let your bot reference data from [tables](/studio/concepts/tables) in its responses
+
+---
+
+## Create a Knowledge Base
+
+To create a Knowledge Base:
+
+1. Navigate to the
**Knowledge Base** menu in the studio.
+2. Select **New Knowledge Base**.
+
+---
+
+## Add sources
+
+Once you've created a Knowledge Base, you can [add sources to it](/studio/concepts/knowledge-base/add-sources):
+
+
+
+
+
+
+
+
+
+
+Your bot will reference these sources when searching for an answer to a user's question.
+
+---
+
+## Search a Knowledge Base
+
+Your bot searches Knowledge Bases differently depending on whether it's executing an [Autonomous Node](/studio/concepts/nodes/autonomous-node) or a [Standard Node](/studio/concepts/nodes/introduction#standard-nodes):
+
+### Using an Autonomous Node
+
+
+ Since your bot only references Knowledge Bases when they're needed, they're useful for de-cluttering your [Autonomous
+ Node's prompt](/studio/concepts/nodes/autonomous-node#be-specific).
+
+
+The default Autonomous Node in a bot's [Main Workflow](/studio/concepts/workflows) contains a **Search Knowledge** Card that searches all Knowledge Bases by default. This means that a newly created AI agent is already equipped to search your Knowledge Bases.
+
+You can scope which Knowledge Bases the Autonomous Node searches using the Search Knowledge Card's configuration menu:
+
+1. Open the drop-down menu under **Included Knowledge Bases**.
+2. Select whichever Knowledge Bases you want to include in searches.
+
+
+ Depending on your needs, you can also add multiple Search Knowledge Cards to your Autonomous Node. For more
+ information, check out the guide on [searching multiple Knowledge Bases](#search-multiple-knowledge-bases).
+
+
+### Using a Standard Node
+
+Since Standard Nodes don't use AI to generate responses, they don't consult your Knowledge Bases by default. To make your bot search your Knowledge Bases within a Standard Node, you can use:
+
+- A [Capture Information Card](/studio/concepts/cards/capture-information#raw-input)
+- A **Query Knowledge Bases** Card
+
+
+ Both of these Cards require the [Knowledge Agent](/studio/concepts/agents/knowledge-agent) to work properly—make sure
+ it's enabled.
+
+
+
+ By default, neither of these Cards send their response to the user directly—instead, you can access the response by
+ referencing `turn.KnowledgeAgent.answer`, then send it to the user manually.
+
+
+---
+
+## Search multiple Knowledge Bases
+
+If you're using an [Autonomous Node](/studio/concepts/nodes/autonomous-node), you have two options for searching multiple Knowledge Bases:
+
+### Search all Knowledge Bases simultaneously
+
+If you need your bot to search all selected Knowledge Bases for every user query, you can use a single Search Knowledge Card:
+
+1. [Add a Search Knowledge Card](/studio/concepts/cards/introduction#add-a-card) to your Autonomous Node (if it doesn't already contain one).
+2. Select the Card to open its configuration menu.
+3. Open the drop-down menu under **Included Knowledge Bases**.
+4. Select whichever Knowledge Bases you want to include in searches.
+
+With this configuration, the Autonomous Node performs a search on all the selected Knowledge Bases simultaneously, then orders the results by score. This is useful if:
+
+- You have multiple Knowledge Bases that can answer similar questions
+- You need to combine the answers from different Knowledge Bases in the same message
+
+
+ Generally, searching all Knowledge Bases simultaneously consumes more LLM tokens and has higher latency than [picking
+ which Knowledge Bases to search based on context](#pick-knowledge-bases-to-search-based-on-the-query).
+
+
+### Pick Knowledge Bases to search based on the query
+
+If you need your bot to search certain Knowledge Bases in certain circumstances, you can use multiple Search Knowledge Cards:
+
+1. [Add multiple Search Knowledge Cards](/studio/concepts/cards/introduction#add-a-card) to your Autonomous Node.
+2. Configure each Card's **Included Knowledge Bases** depending on your needs.
+
+With this configuration, the Autonomous Node views each Search Knowledge Card as a different tool, and picks one to search based on the user's query. This is useful if you have distinct Knowledge Bases that you need to query in different circumstances, and want to avoid overlap between them.
+
+
+ For this configuration to work, you need to specify instructions in each Search Knowledge Card's **Instructions** field. Otherwise, the Autonomous Node won't be able to tell the two Cards apart, and will pick one randomly.
+
+For example, you could add these instructions for questions about company policies:
+
+
+
+
+
+
+And these instructions for questions about pricing:
+
+
+
+
+
+
+
+
+---
+
+## Handle no answer found
+
+If your Workflow has an Autonomous Node, your bot will generate an appropriate response when it doesn't find an answer in the Knowledge Base. However, you can also program a custom response:
+
+1. In your Autonomous Node, add a [Transition](/studio/concepts/cards/flow-logic#transition) Card.
+2. In the Card's **Condition** field, paste the following:
+
+```javascript
+{
+ {
+ !event.state.agentVariables.KnowledgeAgent.turn.answer
+ }
+}
+```
+
+3. Add the following to your Autonomous Node's prompt:
+
+```markdown
+Transition when no answer is found in the Knowledge Base.
+```
+
+Now, your bot will activate the Transition Card whenever it doesn't find an answer in the Knowledge Base. You can handle the transition however you want—for example, with a Node that sends a custom error message.
+
+---
+
+## Storage limit
+
+Information you store in Knowledge Bases counts towards your [Vector DB Storage](/get-started/configure-your-workspace#vector-db-storage), which depends on your [Botpress plan/add-ons](https://botpress.com/pricing).
+
+---
+
+## Troubleshooting
+
+If your bot isn't returning the expected results, you can try troubleshooting it in a few different ways:
+
+### Check logs
+
+Your bot's [logs](/studio/concepts/debugger-logs-json#logs) display:
+
+- The exact query that was sent to the Knowledge Base
+- The results (including source name, content preview, amount of tokens used by the content, row metadata if the source is a table) if there are any matches
+
+Using that information, you can try refining what's sent to the Knowledge Base (or the sources themselves).
+
+### Inspect responses
+
+If you're using an Autonomous Node to search Knowledge Bases, you can use the [Inspect](/studio/concepts/nodes/autonomous-node#check-the-inspect-window) window to analyze your bot's process when searching Knowledge Bases.
diff --git a/src/content/docs/studio/concepts/knowledge-base/knowledge-base-best-practices.mdx b/src/content/docs/studio/concepts/knowledge-base/knowledge-base-best-practices.mdx
new file mode 100644
index 0000000..89cc554
--- /dev/null
+++ b/src/content/docs/studio/concepts/knowledge-base/knowledge-base-best-practices.mdx
@@ -0,0 +1,94 @@
+---
+title: Knowledge Base Best Practices
+description: >-
+ Set up Knowledge Bases effectively by prioritizing structured data, ensuring
+ data quality, and using automated ingestion tools.
+sidebarTitle: Best practices
+---
+
+import { Note } from '@/components/callouts'
+
+The efficiency of your agent relies heavily on the quality of the data fed into the Knowledge Base. Here are some best practices to follow when setting up your Knowledge Base:
+
+## Structured vs. Unstructured Information
+
+The success of your bot depends on how well the information in your KB is structured:
+
+Structured Data refers to any kind of information that requires associating two or more records. For example, a Table that contains information about User emails, IDs, and products would be considered structured data.
+
+Unstructured Data refers to any kind of information that doesn't associate multiple records. For example, this might include files like call transcripts, meeting notes, or product descriptions.
+
+## Data Quality
+
+The quality of the data you feed into the KB directly impacts the quality of your agent's responses. Ensure the information is accurate, up-to-date, and free of unnecessary or redundant details.
+
+Poor-quality data will lead to poor agent performance. When planning an AI Agent project that requires KB ingestion, consider doing a redundant, obsolete, or trivial (ROT) analysis of the KB source.
+
+Good-quality data also includes organized data. For example, if you're answering questions about multiple knowledge products, consider separating them into separate KBs, and segregate your agent's access to each KB based on the context of the conversation.
+
+## Choosing the Right Knowledge Type
+
+When populating your KB, use the correct type based on the nature of your information.
+
+For instance, **Tables** are best suited for structured data. If your information can be classified by attributes or specific fields, using Tables will make it easier for your agent to search and extract data.
+
+Use **Rich Text** for unstructured but logically organized content. It’s a great solution when Tables aren’t feasible.
+
+Use **Documents** when your data can’t be easily represented as structured or plain text. Keep in mind that when documents are uploaded, any native styling or images is removed, and the file is converted to markdown in order to be read by an LLM.
+
+## Using Website Crawlers and Search Engines
+
+Botpress offers flexible options for ingesting website data into the KB:
+
+### If you have a valid sitemap
+
+If your website has a valid sitemap, use the Website crawler, which ingests information more effectively. Consider using a sitemap finder and/or validator to verify your sitemap's validity for this purpose.
+
+### If you don't have a valid sitemap
+
+If your website lacks a valid sitemap, use the Search The Web feature, which relies on Bing search to extract relevant information from the web. This will perform a web search each time a user queries information from the relevant KB.
+
+For manual, specific crawling tasks, you can integrate additional solutions or manually validate crawled content.
+
+## Use the Autonomous Node
+
+For KBs built with Tables, we recommend using the Autonomous Node. It's pre-configured to search and return relevant answers from a KB source.
+
+
+Note
+
+There are specific configurations in order to ensure the Autonomous Node behaves as expected.
+
+[Learn more here.](/studio/concepts/nodes/autonomous-node)
+
+
+
+## Other knowledge ingestion methods
+
+In addition to manually uploading files, Botpress provides automated methods for ingesting data into the KB.
+
+### Direct API Calls (Files API)
+
+You can integrate Botpress with your existing systems and applications to insert documents or other data directly into the KB.
+
+#### Example
+
+Your CRM system sends updated product info to Botpress KB automatically when a new product is added.
+
+### Fixed Scheduler (cron job)
+
+Set up a cron job that periodically calls your APIs to fetch data, which can then be synced to a KB or table in Botpress using an Execute Code Card.
+
+#### Example
+
+A nightly task pulls inventory data from your ERP system, updating a table in the KB with new product details.
+
+### Webhook (Trigger)
+
+External systems (such as Jira, Zendesk, or other third-party apps) can push data directly to Botpress through webhooks. In Botpress, this data can be processed and synced to a KB or table via an Execute Code Card.
+
+#### Example
+
+When a new support ticket is created in Zendesk, a webhook sends relevant details to Botpress to keep the bot updated with the latest customer issues.
+
+Adding extra preprocessing steps in the Execute Code Card can ensure the incoming data is well-prepared for the KB.
diff --git a/src/content/docs/studio/concepts/library.mdx b/src/content/docs/studio/concepts/library.mdx
new file mode 100644
index 0000000..1b2aa87
--- /dev/null
+++ b/src/content/docs/studio/concepts/library.mdx
@@ -0,0 +1,106 @@
+---
+title: Library
+description: >-
+ Repository for managing global Intents and Entities, enabling the extraction
+ and classification of messages.
+icon: Bookmark
+---
+
+import { Info, Warning } from '@/components/callouts'
+
+
+ The Library tab is **deprecated**. Only bots that already created intents and entities will be able to use it.
+
+For Intents, use the [AI Transition Card](/studio/concepts/cards/ai/ai-transition). For Entities, use the [AI Task Card](/studio/concepts/cards/ai/ai-task).
+
+
+
+The NLU Library is a key feature within Botpress, designed to manage and organize global Intents and Entities. These components are essential for understanding and processing user input, enabling your bot responds accurately and effectively.
+
+## Intents
+
+Intents are the backbone of understanding in a bot. They represent the purpose or goal behind a user's message, allowing the bot to determine the appropriate response. Each intent can have multiple utterances—different ways users might express the same request.
+
+For example, an "Ordering a coffee" intent could include utterances like:
+
+"I want coffee"\
+"I'd like some coffee, please"\
+"Do you have a decaf espresso?"\
+"Hi. I'd like to order a latte, please.
+
+The bot compares user messages against these utterances to match them to the correct intent with the highest confidence score.
+
+| User Message | Intent Matched | Confidence |
+| :------------------------------------------ | :------------: | ---------: |
+| I would like to order a coffee. | place-order | 0.97 |
+| An espresso, please | place-order | 0.91 |
+| Can you please give me a double cappuccino? | place-order | 0.96 |
+
+### Creating an Intent
+
+To create a new intent:
+
+1. Navigate to the Library
+2. Click the + button to add a new intent
+3. Provide a simple name for the intent (e.g., "order coffee")
+
+### Adding Utterances
+
+After creating an intent, you need to define utterances that represent different ways a user might express the same intent.
+
+1. In the intent creation window, enter at least 10 utterances
+2. Save your changes
+
+Utterances currently support a maximum of 280 characters each.
+
+### Inline Intents
+
+Inline intents are specialized intents that can be defined directly on transitions within a Workflow. They function like global intents but are limited to specific scenarios within a conversation, making them ideal for context-sensitive tasks.
+
+To use inline intents:
+
+- Define them directly on a transition within your Workflow
+- Add relevant utterances
+
+## Entities
+
+Entities are data points or parameters that provide additional context within an intent. They allow your bot to extract and normalize specific details from a user's message, such as a date, time, color, or any other relevant piece of information.
+
+
+Example
+
+The place-order intent contains the following entities:
+
+**caffeine** that specifies if the coffee is caffeinated or decaffeinated.
+
+**size** for a single or a double shot.
+
+**drink** that specifies the kind of drink asked for.
+
+Attached to NLU extraction, you will find an entities property which is an array of System and Custom entities.
+
+
+
+### Custom Entities
+
+Botpress provides two types of custom entities: pattern and list entities. To define a custom entity, go to the Library tab of the Explorer. From there, you can define your custom entities which will be available for any input message treated by your bot. Go ahead and click on New entity.
+
+### Using Entities
+
+You may access and use entity data by looking up the event.nlu.entities variable in your hooks, Workflow transitions or Execute Code cards.
+
+### List Entities
+
+List extraction behaves similarly to pattern extraction. However, you'll be able to add different occurrences of your entity with corresponding synonyms.
+
+Let's take Airport Codes as an example:
+
+Extraction will go like this: User said Type Value "Find a flight from SFO to Mumbai" "Airport Codes" ["SFO", "BOM"]
+
+### Pattern Entities
+
+Pattern or Regular Expression Extraction allows you to extract information presented in a format that can be described using Regular Expression (RegEx). Once you've created a pattern entity, Botpress Native NLU will perform a regex extraction on each incoming message and add it to event.nlu.entities.
+
+Example:
+
+Given a Pattern Entity definition with `[A-Z]\{3}-\[0-9]\{4}-[A-Z]\{3}` as a pattern: Extraction will go like this: User said Type Value Find product BHZ-1234-UYT SKU BHZ-1234-UYT
diff --git a/src/content/docs/studio/concepts/nodes/assets/an-dark.png b/src/content/docs/studio/concepts/nodes/assets/an-dark.png
new file mode 100644
index 0000000..d2185c4
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/an-dark.png differ
diff --git a/src/content/docs/studio/concepts/nodes/assets/an.png b/src/content/docs/studio/concepts/nodes/assets/an.png
new file mode 100644
index 0000000..ca0a858
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/an.png differ
diff --git a/src/content/docs/studio/concepts/nodes/assets/node-dark.png b/src/content/docs/studio/concepts/nodes/assets/node-dark.png
new file mode 100644
index 0000000..e7a992f
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/node-dark.png differ
diff --git a/src/content/docs/studio/concepts/nodes/assets/node.png b/src/content/docs/studio/concepts/nodes/assets/node.png
new file mode 100644
index 0000000..aa5c42e
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/node.png differ
diff --git a/src/content/docs/studio/concepts/nodes/assets/transition-dark.png b/src/content/docs/studio/concepts/nodes/assets/transition-dark.png
new file mode 100644
index 0000000..f4ecabd
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/transition-dark.png differ
diff --git a/src/content/docs/studio/concepts/nodes/assets/transition.png b/src/content/docs/studio/concepts/nodes/assets/transition.png
new file mode 100644
index 0000000..bf06f8e
Binary files /dev/null and b/src/content/docs/studio/concepts/nodes/assets/transition.png differ
diff --git a/src/content/docs/studio/concepts/nodes/autonomous-node.mdx b/src/content/docs/studio/concepts/nodes/autonomous-node.mdx
new file mode 100644
index 0000000..b2250fe
--- /dev/null
+++ b/src/content/docs/studio/concepts/nodes/autonomous-node.mdx
@@ -0,0 +1,395 @@
+---
+title: Autonomous Node
+---
+
+import { Picture } from 'astro:assets'
+import anDarkImg from './assets/an-dark.png'
+import anImg from './assets/an.png'
+
+import Accordion from '@/components/Accordion.astro'
+import AccordionGroup from '@/components/AccordionGroup.astro'
+import Tab from '@/components/tabs/Tab.astro'
+import Tabs from '@/components/tabs/Tabs.astro'
+import { Tip, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+The Autonomous Node **uses AI to make decisions**—like what your bot should say or what tools it should use.
+
+Unlike a [standard Node](/studio/concepts/nodes/introduction#standard-node), which executes its [Cards](/studio/concepts/cards/introduction) one by one, the Autonomous Node uses a Large Language Model (LLM) to decide when to execute tools. It can understand the conversation's context, write responses to users, and leverage the tools you give it.
+
+
+
+
+
+
+You can use the Autonomous Node to build an independent AI agent that:
+
+- Aligns with your brand
+- Learns your users' needs
+- Doesn't need human intervention to take actions
+
+---
+
+## Add an Autonomous Node
+
+By default, every bot has an Autonomous Node installed in its main [Workflow](/studio/concepts/workflows). If you need to create a new Autonomous Node:
+
+1. Right-click anywhere in a Workflow.
+2. Select **Autonomous Node**.
+
+---
+
+## Configuration
+
+
+ If your main Workflow contains an Autonomous Node, you can quickly update its configuration from the Studio's
+ [Home](/studio/concepts/home) page.
+
+
+Select your Autonomous Node to open its configuration menu. Here's a breakdown of the configuration options:
+
+- **Instructions**: This field is your Autonomous Node's main prompt. Provide clear guidelines in this section—the more specific you are, the better the agent’s decision-making.
+
+ For a detailed guide to prompting, check out the [Prompting tips](#prompting-tips) section.
+
+- **Variables**: This section lets you [give your Autonomous Node access to variables](#give-access-to-variables).
+
+- **Tools**: This section lets you [add tools](#add-tools) that the Autonomous Node can use.
+
+- **Search Knowledge**: This section lets you specify which Knowledge Bases your Autonomous Node can refer to.
+
+- **Workflows**: This section lets you provide additional [Workflows](/studio/concepts/workflows) to the Autonomous Node, which it can execute during a conversation.
+
+- **Exit Conditions**: This section lets you define the conditions under which your Autonomous Node should [exit its loop](#advanced-settings).
+
+### Add tools
+
+You can add tools to your Autonomous Node to expand its capabilities. The LLM powering the Autonomous Node will decide when to use these tools based on your instructions (and the conversation's context).
+
+You can refer to tools using natural language in your instructions—however, your bot may generate better responses if you [refer to them using code](#refer-to-tools-directly).
+
+### Give access to variables
+
+By default, Autonomous Nodes can't read or update [variables](/studio/concepts/variables/overview). If you need to give an Autonomous Node access to a variable:
+
+1. Select the Autonomous Node to open its configuration menu.
+2. Under **Variables**, select **+ Add variable(s)**.
+3. Select any variable to let the Autonomous Node read it.
+4. If you also want to give the Autonomous Node write access to the variable, check **Allow write access**.
+
+
+ If you don't see the option to **+ Add variable(s)**, make sure you've [created at least one
+ variable](/studio/concepts/variables/overview#create-a-variable).
+
+
+### Make your Autonomous Node non-conversational
+
+By default, your Autonomous Node responds to every user message in a loop until one of its [exit conditions](#configuration) are met. If you'd rather your Autonomous Node just execute logic without responding to user messages, you can disable **Advanced Settings > Loops until exit condition**.
+
+When this setting is disabled, your Autonomous Node:
+
+1. Processes the user's message
+2. Performs some action (if necessary), like executing a tool
+3. Transitions to the next Node in the Workflow without responding to the user.
+
+This is useful if you want AI to handle logic behind the scenes, but still hard-code the bot's response.
+
+### Override default models
+
+By default, all Autonomous Nodes use the LLMs set in your [Bot Settings](/studio/concepts/bot-settings#default-llms). However, you can override these models for individual Autonomous Nodes if needed:
+
+1. Select the Autonomous Node to open its configuration menu.
+2. Open **
Advanced settings**.
+3. Enable either:
+ - **Override default model**: Overrides the default LLM used for generating responses
+ - **Override default RAG model**: Overrides the default LLM used for Retrieval-Augmented Generation (RAG) tasks, like answering questions based on [Knowledge Base](/studio/concepts/knowledge-base/introduction) content
+
+### Enable Vision Agent
+
+You can enable the [Vision Agent](/studio/concepts/agents/vision-agent) if you want your Autonomous Node to extract text content from incoming images. Toggle **Advanced Settings > Vision Agent > Extract from Incoming Images** to enable or disable this option.
+
+---
+
+## Prompting tips
+
+Here are some tips and guidelines to help you write better prompts for the Autonomous Node.
+
+
+
+You can also check out the following resources for more general information about successful LLM prompting:
+
+- [Best practices for prompt engineering with the OpenAI API](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-the-openai-api)
+- [Building Systems with the ChatGPT API](https://www.deeplearning.ai/short-courses/building-systems-with-chatgpt/)
+- [ChatGPT Prompt Engineering for Developers](https://www.deeplearning.ai/short-courses/chatgpt-prompt-engineering-for-developers/)
+
+
+
+### Use Markdown
+
+To create a structured prompt, we recommend using [Markdown syntax](https://www.markdownguide.org/basic-syntax/) like headers, bullet points, and bold text. This helps the Autonomous Node recognize the hierarchy of your instructions.
+
+
+ ```markdown Instructions wrap
+ ## Identity
+ You are the Customer Support AI Agent for [COMPANY NAME]. Your role is to interact with customers, address their inquiries, and provide assistance with common support topics.
+
+## Scope
+
+- Focus on customer inquiries about orders, billing, account issues, and general support.
+- **Don't handle advanced technical support or sensitive financial issues**.
+- Redirect or escalate issues outside your expertise to a human agent.
+
+## Response Style
+
+- Maintain a friendly, clear, and professional tone.
+- Keep responses brief and to the point.
+- **Never use unexplained jargon or acronyms.**
+- **Always confirm and echo user inputs before proceeding.**
+
+````
+
+
+### Be specific
+
+Instead of vague commands, use specific language that guides the agent clearly. The more specific you are, the better chance you have of your Autonomous Node behaving as expected.
+
+
+#### Don't over-prompt!
+
+If your prompt is long and detailed but the Autonomous Node isn't behaving how you'd expect, **try trimming the prompt down**. An overly convoluted (or contradictory) prompt can confuse the LLM and lead to poor performance or hallucinations.
+
+
+### Guide the conversation
+
+{/* vale Botpress.workflows = NO */}
+Provide clear instructions on how the conversation should flow. This could include:
+{/* vale Botpress.workflows = YES */}
+
+- Greeting instructions
+- Conditions for [transitioning to sub-Workflows](/studio/concepts/workflows#transition-to-a-workflow)
+- Closing instructions
+
+
+```markdown Instructions wrap
+## Instructions
+- **Greeting**: Start every conversation with a friendly welcome.
+ _Example_: "Hi, welcome to [COMPANY NAME] Support! How can I help you today?"
+
+- **Escalation**: When a customer query becomes too complex or sensitive, transition to the "Human agent" sub-Workflow and notify the customer that you'll escalate the conversation to a human agent.
+ _Example_: "I’m having trouble resolving this. Let me get a human agent to assist you further."
+
+- **Closing**: End interactions by confirming that the customer's issue has been addressed.
+ _Example_: "Is there anything else I can help you with today?"
+ ```
+
+
+### Refer to tools directly
+
+Your bot uses various code-based tools to perform actions. Although you can write your instructions in natural language, your bot may generate better responses if you refer to these tools directly.
+
+You can view a full list of tools your bot currently has access to in the [Inspect window](#inspect-window).
+
+
+
+ Here's a list of built-in tools that every bot can use by default:
+
+ - `global.think`: Allows the Node to process a response or pause briefly.
+ - `global.search`: Queries an internal knowledge base for relevant information.
+ - `clock.setReminder`: Sets a reminder for future tasks or responses.
+ - `global.Message`: Sends a text message to the user as a response.
+
+
+
+ This prompt tells the Autonomous Node to search the web when it can't find an answer in the internal Knowledge Base:
+
+ ```markdown Instructions wrap
+ If you can't answer the user's question with `global.search`, use `browser.webSearch`.
+ ```
+
+
+
+
+ This prompt narrows when each search tool runs so the Node doesn't pull unrelated content:
+
+ ```markdown Instructions wrap
+ **Tool boundaries**
+ - Use `global.search` only for questions about [your scoped topic—for example course content or order support]. Do **not** use it for general pricing, marketing, or unrelated small talk unless the user explicitly needs a documented policy from the knowledge base.
+ - Use `browser.webSearch` only when `global.search` does not contain a sufficient answer **and** the question still falls within that same scope. Do not use web search for out-of-scope requests—politely decline instead.
+ ```
+
+
+
+
+ When the base URL lives in a [Workflow variable](/studio/concepts/variables/scopes/workflow), this prompt tells the Autonomous Node how to add a start time (replace the variable name with one you have given the Node access to):
+
+ ```markdown Instructions wrap
+ **Video links**
+ If the user wants a link to the lesson video, the base URL is in `workflow.contentLinks`. To jump to a specific second, append a `t` query in seconds (e.g. 15 seconds → add `?t=15` or `&t=15` depending on whether the URL already has query parameters).
+ ```
+
+
+
+ Here are the tools your bot uses to make transitions:
+
+ - `global.`: [Transitions to a sub-Workflow](/studio/concepts/workflows#transition-to-a-workflow).
+ - `workflow.transition`: Transitions to a Node that's connected to the Autonomous Node.
+
+
+ This prompt tells the Autonomous Node to transition to a custom sub-Workflow (`global.checkout`) when the user wants to checkout with their current cart:
+
+ ```markdown Instructions wrap
+ When the user wants to checkout with their current cart, use `global.checkout`.
+ ```
+
+
+
+
+ This pattern is for leaving the Autonomous Node for a structured sub-Workflow after saving a value from the conversation. The Autonomous Node needs [read and write access](#give-access-to-variables) to the variable you mention:
+
+ ```markdown Instructions wrap
+ When the user asks for deeper details about an email they mentioned, use `workflow.transition` to move to the **Enrich contact** Node. Before transitioning, set `workflow.requestedEmail` to that email address.
+ ```
+
+ Replace the Node name, variable name, and trigger phrase with whatever matches your bot.
+
+
+
+
+ This prompt combines `global.Message` with `workflow.transition` when the user picks a numeric option. Connect each target with a **Transition** card on the canvas first so `workflow.transition` is valid:
+
+ ```markdown Instructions wrap
+ If the user sends **1**, thank them briefly with `global.Message`, then use `workflow.transition` to go to the **Self-serve** node. If they send **2**, use `workflow.transition` to go to the **Guided setup** node.
+ ```
+
+
+
+
+ You can also directly refer refer to any tools from external integrations.
+
+
+ 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`.
+ ```
+
+
+
+
+---
+
+## Example instructions
+
+Here's an example of complete instructions for an Autonomous Node:
+
+```markdown Instructions expandable wrap
+## Identity
+You are the Customer Support AI Agent for [COMPANY NAME]. Your role is to interact with customers, address their inquiries, and provide assistance with common support topics.
+
+## Scope
+- Focus on customer inquiries about orders, billing, account issues, and general support.
+- Don't handle advanced technical support or sensitive financial issues.
+- Redirect or escalate issues outside your expertise to a human agent.
+
+## Responsibility
+- Initiate interactions with a friendly greeting.
+- Guide the conversation based on customer needs.
+- Provide accurate and concise information.
+- Escalate to a human agent when customer inquiries exceed your capabilities.
+
+## Response Style
+- Maintain a friendly, clear, and professional tone.
+- Keep responses brief and to the point.
+- Use buttons for quick replies and easy navigation whenever possible.
+
+## Ability
+- Delegate specialized tasks to AI-Associates or escalate to a human when needed.
+
+## Guardrails
+- **Privacy**: Respect customer privacy; only request personal data if absolutely necessary.
+- **Accuracy**: Provide verified and factual responses coming from Knowledge Base or official sources. Avoid speculation.
+
+## Instructions
+- **Greeting**: Start every conversation with a friendly welcome.
+_Example_: "Hi, welcome to [COMPANY NAME] Support! How can I help you today?"
+
+- **Escalation**: When a customer query becomes too complex or sensitive, notify the customer that you'll escalate the conversation to a human agent.
+_Example_: "I’m having trouble resolving this. Let me get a human agent to assist you further."
+
+- **Closing**: End interactions by confirming that the customer's issue has been addressed.
+_Example_: "Is there anything else I can help you with today?"
+````
+
+---
+
+## Troubleshooting
+
+This section contains troubleshooting tips to understand how your Autonomous Node is behaving, why it made certain decisions, and how you can course-correct when it's not behaving as expected.
+
+### Check the Inspect window
+
+The **Inspect** window displays information about the Autonomous Node's process, reasoning, and functions. If you notice that the Node isn’t responding correctly or seems to ignore certain instructions, inspecting will reveal whether it has misunderstood the prompt or failed to execute a specific tool.
+
+To access the **Inspect** window:
+
+1. Start a chat with your bot in the Studio's [emulator](/studio/concepts/emulator).
+2. Select **Inspect** on any of its responses.
+
+Here's a breakdown of how to use the **Inspect** window:
+
+
+
+ This section displays all tools available to the Autonomous Node. Each time you add a new Card or make a change to the Node's configuration, the **Tools** list is updated.
+
+ - Ensure that the tools listed match what you expect to be available in the Node's decision-making process.
+ - Ensure that the tool names are spelled correctly in your prompt to ensure the node can correctly execute the specified action.
+
+
+
+ The Autonomous Node typically tries to execute all instructions within one or two iterations. The number of iterations depends on the complexity of the prompt and how the Node analyzes it.
+
+ For more complex tasks, the Node might take multiple iterations to gather data, make decisions, or fetch external information.
+
+ By reviewing the Iterations tab, you can understand:
+
+ - How many iterations were required for the Node to reach its final decision
+ - What caused the Node to take multiple steps (e.g., fetching additional data from tools like `global.search` or `browser.webSearch`)
+ - Why a particular outcome was achieved
+
+
+
+
+### Choose the right model
+
+Lower-performance LLMs may struggle with the complexity of operations typically executed by the Autonomous Node. For this reason, we recommend using a high-performing model to power Autonomous Nodes, roughly equivalent to a model like OpenAI's GPT-4.1.
+
+A smaller LLM might result in parts of the prompt being truncated, specifically the definition wrapper that Botpress adds to ensure the LLM understands how the tools function, or what parameters are required.
+
+### Check your LLMz version
+
+Always make sure you are using the latest stable version of LLMz. This is the autonomous engine that directs the Autonomous Node to work. It also contains bug fixes, making the prompts more agnostic to variance between LLMs.
+
+You can check/change your LLMz version in your [Bot Settings](/studio/concepts/bot-settings#llmz-version).
diff --git a/src/content/docs/studio/concepts/nodes/introduction.mdx b/src/content/docs/studio/concepts/nodes/introduction.mdx
new file mode 100644
index 0000000..bf6fe91
--- /dev/null
+++ b/src/content/docs/studio/concepts/nodes/introduction.mdx
@@ -0,0 +1,172 @@
+---
+title: Nodes
+sidebarTitle: Introduction
+---
+
+import { Picture } from 'astro:assets'
+import nodeDarkImg from './assets/node-dark.png'
+import nodeImg from './assets/node.png'
+import transitionDarkImg from './assets/transition-dark.png'
+import transitionImg from './assets/transition.png'
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+{/* vale Botpress.workflows = NO */}
+
+Nodes are the **primary units of conversational logic** in your bot.
+
+Think of a Node as a single step in a conversation. It executes a sequence of actions—like sending a message, capturing information from a user, or performing a task—then transitions to the next Node.
+
+
+
+
+
+
+---
+
+## Overview
+
+An individual Node's behaviour depends on what [Cards](/studio/concepts/cards/introduction) it contains. You can add any combination of Cards to a Node to achieve your desired behaviour.
+
+A Node [transitions to the next Node](#transition-between-Nodes) when either:
+
+- It finishes executing all its Cards
+- One of its Cards manually transitions to a new Node. You can set up manual transitions based on [user choice](/studio/concepts/cards/capture-information), [true/false conditions](/studio/concepts/cards/flow-logic), and more.
+
+
+ Some Nodes have specific properties that make them behave differently—check out [Types of Node](#types-of-node) for
+ more details.
+
+
+
+
+A group of Nodes is called a [Workflow](/studio/concepts/workflows). You can use Workflows to organize your bot's
+behaviour.
+
+
+
+---
+
+## Usage
+
+### Add a Node
+
+To add a new Node:
+
+1. Right-click anywhere in a Workflow.
+2. Select a [type of Node](#types-of-node) from the popup menu.
+
+### Transition between Nodes
+
+To create a transition between two Nodes:
+
+1. Select and hold the right edge of the Node you want to transition _from_.
+2. Drag outwards, then release on the left edge of the Node you want to transition _to_. This will create a transition between the two Nodes:
+
+
+
+
+
+
+### Move a Node
+
+To move a Node around your Workflow, just drag and drop it wherever you like.
+
+### Rename a Node
+
+To rename a Node, just select its title and type in a new name.
+
+### Test a Node
+
+You can test a specific Node in the Studio's [Emulator](/studio/concepts/emulator). Just select any Node, then press the
Play button to start a conversation with your bot from that Node.
+
+### Copy/Delete a Node
+
+Right-click any Node to copy or delete it.
+
+---
+
+## Types of Node
+
+Nodes behave differently and have different available Cards based on their type. Here's a breakdown of each type of Node:
+
+### Standard Node
+
+Standard Nodes execute each of their Cards one-by-one, then transition to the next Node. They're the most basic type of Node, and are useful when you need full control over your bot's behaviour.
+
+### Autonomous Node
+
+The Autonomous Node uses AI to make decisions—like what your bot should say or what tools it should use.
+
+Unlike a standard Node, which executes its Cards one by one, the Autonomous Node uses a Large Language Model (LLM) to decide when to execute its Cards. It can understand the conversation’s context, write responses to users, and leverage the tools you give it.
+
+
For more information, check out the [Autonomous Node guide](/studio/concepts/nodes/autonomous-node).
+
+### Start Node
+
+The Start Node is the entrance point to every conversation with your bot. It's only available in the [Main Workflow](/studio/concepts/workflows#main), can't be modified/deleted, and can't use Cards.
+
+You can select the Start Node to configure:
+
+- Which [Knowledge Base](/studio/concepts/knowledge-base/introduction) your bot has access to
+- Whether your bot has access to the [Vision Agent](/studio/concepts/agents/vision-agent)
+
+### Entry Node
+
+The Entry Node is the start of every Workflow in your bot (except for the [Main Workflow](/studio/concepts/workflows#main)). It executes whenever you [transition to a new Workflow](/studio/concepts/workflows#transition-to-a-workflow) and can't be deleted.
+
+The only Cards you can add to an Entry Node are:
+
+- [Expression/Intent](/studio/concepts/cards/flow-logic) Cards
+- [Log](/studio/concepts/cards/utilities#log) Cards
+
+
+ You can toggle variables within an Entry Node—check out the guide to [passing variables between
+ Workflows](/studio/concepts/variables/pass-between-workflows) for more information.
+
+
+### Exit Node
+
+The Exit Node is the end of every custom Workflow in your bot ([built-in Workflows](/studio/concepts/workflows#built-in-workflows) end with an [End Node](/studio/concepts/nodes/introduction#end-node) instead). It defines the exit point for the Workflow—each custom Workflow must contain at least one Exit Node.
+
+Exit Nodes can't use Cards.
+
+
+ You can configure the Exit Node to pass a variable back to its parent Workflow—check out the guide to [passing
+ variables between Workflows](/studio/concepts/variables/pass-between-workflows) for more information.
+
+
+### End Node
+
+The End Node is the end point of every conversation with your bot. It has no configuration options and can't use Cards.
+
+Only End Nodes can explicitly end a conversation, which:
+
+- Clears the conversation session
+- Erases all variables and user data
+- Resets the bot to its initial state.
+
+Each [built-in Workflow](/studio/concepts/workflows#built-in-workflows) must contain at least one End node. You can also add End Nodes to custom Workflows.
+
+### Triggers
+
+Triggers are a special kind of Node that only execute when a certain event occurs. They're different from regular Nodes in a few ways:
+
+- You can’t transition from a regular Node to a Trigger. Any Triggers in your Workflow will only execute when the event they listen for occurs.
+- Unlike other Nodes, you can’t add or remove Cards from a Trigger. Each Trigger is built around a single Card that determines when it executes.
+
+
For more information, check out the [Triggers guide](/studio/concepts/triggers).
+
+### Exception handlers
+
+Exception handlers are Nodes that execute whenever your bot encounters an error. They're optional, have no configuration options, and can't contain any Cards.
+
+By default, your bot uses the built-in [Error Workflow](/studio/concepts/workflows#error) to handle errors, regardless of which Workflow the error occurred in—exception handlers let you handle errors differently for specific Workflows.
+
+You can only add exceptional handlers to the [Main Workflow](/studio/concepts/workflows#main) or to custom Workflows. Each Workflow can contain one exception handler.
+
+### Comments
+
+You can leave comments, images or videos in your Workflow. They have no effect on your bot's behaviour—you can use them to annotate your Workflows and make them easier to understand for any collaborators.
diff --git a/src/content/docs/studio/concepts/schema.mdx b/src/content/docs/studio/concepts/schema.mdx
new file mode 100644
index 0000000..7e22aa1
--- /dev/null
+++ b/src/content/docs/studio/concepts/schema.mdx
@@ -0,0 +1,14 @@
+---
+title: Schema
+excerpt: ''
+deprecated: false
+hidden: true
+metadata:
+ title: ''
+ description: ''
+ robots: index
+next:
+ description: ''
+---
+
+You can create custom object schemas (variable types) to validate the data you are working with. This is useful when you want to ensure that the data you are working with is in the correct format.
diff --git a/src/content/docs/studio/concepts/schemas.mdx b/src/content/docs/studio/concepts/schemas.mdx
new file mode 100644
index 0000000..32ee25d
--- /dev/null
+++ b/src/content/docs/studio/concepts/schemas.mdx
@@ -0,0 +1,188 @@
+---
+title: Schemas
+description: Blueprint that defines the structure, format, and validation rules for data.
+icon: CircleDashed
+---
+
+import { Picture } from 'astro:assets'
+import inputTypeTextAdvanceImg from './assets/input-type-text-advance.png'
+import inputTypeTextImg from './assets/input-type-text.png'
+
+A schema is a blueprint that defines the structure, required fields, data types, and validation rules for a piece of data. In Botpress, schemas are primarily used to ensure that data passed between various components—such as actions, modules, or API requests—meets the expected format and constraints.
+
+Schemas are useful for:
+
+- **Data Validation**: Preventing errors by ensuring that data adheres to the expected format.
+- **Consistency**: Enforcing a consistent structure for data across different components.
+- **Error Reduction**: Reducing the likelihood of runtime errors caused by unexpected or malformed data.
+
+{/* vale Botpress.workflows = NO */}
+
+- **Ease of Maintenance**: Making it easier to understand and manage data flow within your Botpress application.
+
+{/* vale Botpress.workflows = YES */}
+
+## Creating and Using Schemas
+
+### JSON Schema Basics
+
+Botpress uses JSON Schema, a standard for describing the structure and validation constraints of JSON documents.
+
+A JSON Schema can define:
+
+- **Types**: The type of data (e.g., string, number, object, array).
+- **Required Fields**: Fields that must be present in the data.
+- **Enum Values**: Specific allowed values for a field.
+- **Nested Structures**: Complex data structures with multiple levels.
+
+### Creating a schema
+
+You can create a new schema by navigating to the Schema menu in the left-hand menu. You can also create a new schema when adding a new variable through the Variables menu.
+
+### Using schemas
+
+You can use schemas instead of selecting a variable type like String or Number. This means that the variable will contain the information in the structure you've defined in your schema.
+
+For example, you might use a variable to contain information about your end user. This variable can use a schema to contain information like email, age, name, and home address, all contained in a single variable and structured by your schema.
+
+## Testing Schemas
+
+Here's a simple demo schema you can create to familiarize yourself with them.
+
+1. Create a schema for a user object with the following properties:
+
+```typescript
+zui.object({
+ name: zui.string(),
+ age: zui.number(),
+ email: zui.string().email(),
+ address: zui.object({
+ street: zui.string(),
+ city: zui.string(),
+ zip: zui.string().length(5),
+ }),
+})
+```
+
+2. Create a Variable of the user schema type and name it `UserInformation`.
+3. \[optionally] you can use these variables as inputs for Workflows, allowing the user to fill in the schema as though it were a form.
+
+### Usage in AI Task
+
+- Task Instructions:
+
+```
+Fetch name, age, email and address from the provided input
+```
+
+- AI Task Input:
+
+```
+Rohan Kokkula, 26, at rohan@email.com, received a mysterious parcel at his doorstep:
+42 Emerald Lane, Mystic Falls, 560078.
+Inside, a map beckoned him to a hidden world beneath Mumbai's bustling streets,
+where history and magic intertwined.
+```
+
+- Store result in variables: Select the Variable we created above.
+
+
+
+## Conditionally Show Inputs - Input trees
+
+We'll show you how to use discriminated unions in Zod to conditionally include fields in an object schema. We'll go through two examples:
+
+1. Changing the type of a variable based on user input.
+2. Conditionally showing an extra setting when an "Advanced Setting" toggle is activated.
+
+
+
+
+
+
+
+#### Example 1: Changing the Type of a Variable
+
+In this example, we'll create a schema that allows a variable (`value`) to be either a string or a number, depending on the user's choice.
+
+```typescript
+z.object({
+ inputData: z.discriminatedUnion('inputType', [
+ z.object({
+ inputType: z.literal('Text'),
+ // When inputType is 'Text', value is a string
+ value: z.string().title('Text Value').placeholder('Enter text'),
+ }),
+ z.object({
+ inputType: z.literal('Number'),
+ // When inputType is 'Number', value is a number
+ value: z.number().title('Numeric Value').placeholder('Enter a number'),
+ }),
+ ]),
+})
+```
+
+##### How It Works
+
+- **`inputType`**: Acts as the discriminator that determines the type of the `value` field.
+- **Discriminated Union**:
+ - If `inputType` is `"Text"`, the schema expects `value` to be a string.
+ - If `inputType` is `"Number"`, the schema expects `value` to be a number.
+
+This approach is useful when you want to change the type of a variable based on a user's selection.
+
+#### Example 2: Conditionally Showing Extra Settings
+
+This example demonstrates how to include an extra field when an "Advanced Setting" toggle is turned on.
+
+```typescript
+z.object({
+ // ... your other inputs
+
+ // Using discriminated union to handle the advanced setting toggle with Yes/No options
+ settings: z.discriminatedUnion('advancedSetting', [
+ z.object({
+ advancedSetting: z.literal('No').describe('Advanced setting is disabled'),
+ // No extra settings when advancedSetting is "No"
+ }),
+ z.object({
+ advancedSetting: z.literal('Yes').describe('Advanced setting is enabled'),
+ // Extra setting when advancedSetting is "Yes"
+ extraSetting: z
+ .string()
+ .title('Extra Setting')
+ .placeholder('Enter extra setting')
+ .describe('Additional setting enabled when the advanced setting is turned on'),
+ }),
+ ]),
+})
+```
+
+##### How It Works
+
+- **`advancedSetting`**: Acts as the discriminator that determines whether to include the `extraSetting` field.
+- **Discriminated Union**:
+ - If `advancedSetting` is `"No"`, the schema doesn't include `extraSetting`.
+ - If `advancedSetting` is `"Yes"`, the schema requires `extraSetting` to be provided.
+
+This pattern is useful when you want to include additional settings only when an "Advanced Setting" option is enabled.
+
+#### Trying it out
+
+Trying it out is very easy!
+
+1. Open Botpress Studio
+2. Create and save the schema with `discriminatedUnion` fields
+3. Create a variable in a Workflow other than main, set its type to the schema's saved name.
+4. Click on the input node for the Workflow, then toggle the variable as an input.
+5. Go to another Workflow and add a card that points to the one with the schema input.
+6. You'll now be able to able to see your input tree in all it's glory!
+
+#### Summary
+
+- **Discriminated Unions** in Zod allow you to conditionally change the shape of an object.
+- They're useful for:
+ 1. Changing the type of a variable based on user input.
+ 2. Conditionally including fields based on a toggle or option.
+
+By using discriminated unions, you can build dynamic and flexible schemas that adapt based on user selections, making your form validation and UI more intuitive and responsive.
diff --git a/src/content/docs/studio/concepts/tables.mdx b/src/content/docs/studio/concepts/tables.mdx
new file mode 100644
index 0000000..5c2ec3a
--- /dev/null
+++ b/src/content/docs/studio/concepts/tables.mdx
@@ -0,0 +1,1000 @@
+---
+title: Tables
+icon: Table
+---
+
+import { Picture } from 'astro:assets'
+import autoComputeImg from './assets/auto-compute.png'
+import codeEditorImg from './assets/code-editor.png'
+import computedColumnSwitchImg from './assets/computed-column-switch.png'
+import editCodeButtonImg from './assets/edit-code-button.png'
+import staleComputeRowImg from './assets/stale-compute-row.png'
+import tableCodeOperationsImg from './assets/table-code-operations.png'
+import tableDependenciesImg from './assets/table-dependencies.png'
+
+import Accordion from '@/components/Accordion.astro'
+import AccordionGroup from '@/components/AccordionGroup.astro'
+import Tooltip from '@/components/Tooltip.astro'
+import YouTube from '@/components/YouTube.astro'
+import { Note, Warning } from '@/components/callouts'
+
+Tables are an essential feature in the explorer, functioning as a local database within your bot's environment. They provide structured storage for various types of data that can be accessed and manipulated as required within your Workflows.
+
+They're particularly useful for storing information that needs to be persisted across multiple sessions, such as user profiles, transaction histories, and other types of data that need to be retrieved and updated over time.
+
+
+Note
+
+You can create up to **10 tables** with **20 columns** and **10,000 rows** in the **Free Plan**. [Get in touch](https://botpress.com/contact-us) if you want to increase the limits. However, the 20 columns per table is a hard limit that can't be increased.
+
+
+
+
+ Table row capacity filling up quicker than you expected? Check your table's **row factor**.
+
+
+ Every table has a row factor that determines the storage limit for each of its rows. When you create a new table, the default row factor is 1—this allows you store up to 4KB of data per row.
+
+ If you need to store more than 4KB of data in each row, you can create a table with a higher row factor. However, increasing the table's row factor makes each row count more towards your table's row limit.
+
+ **Example**: If you create a table with a row factor of 3, each row will have a storage limit of 12KB (because 4KB x 3 = 12KB). This will make each row will count as three rows towards your table's row limit.
+
+ You can check any table's row factor in the bottom-right corner of that table.
+
+
+
+
+
+## Creating a Table
+
+To add a new table, go to the explorer menu and select `Add Table`. You can then give your table a name and add fields to it. Each field has a name and a type. The type determines the kind of data that can be stored in the field. For example, a field with the type `String` can store any text value, while a field with the type `Number` can only store numeric values.
+
+### Making Fields Searchable
+
+You can make a field searchable by checking the `Searchable` checkbox. This will allow you to search for records based on the values in the field. For example, if you have a field called `Name` and you make it searchable, you can search for records based on the name of the person. This is available for fields of type `String`, `Object`, `Array` and [custom schemas](/studio/concepts/schema).
+
+## Types of Fields (Columns)
+
+There are several types of fields you can add to a table. Each field type has a specific purpose and can only store certain types of data. These are the field types you can choose from: `String`, `Number`, `Boolean`, `Date`, `Object`, `Array` and [custom schemas](/studio/concepts/schema).
+
+
+Warning
+
+The number of columns has a hard limit of **20 columns** per table.
+
+
+
+## Filtering Records
+
+Table filters are a powerful feature that allows you to refine and display only the records that meet certain criteria. Filters can be based on specific conditions, such as date ranges, text matches, and numerical comparisons.
+
+### Logical Operators
+
+- **AND**: Use the AND operator when you want all conditions to be true for a record to be displayed. For example, filtering by `createdAt` AND `status` will only show records that match both conditions.
+
+- **OR**: Use the OR operator to display records that match any one of multiple conditions. For example, filtering by `createdAt` OR `updatedAt` will show records that match either one of the conditions.
+
+### Types of Rules
+
+Rules define the individual conditions applied to each column of data.
+
+- `is equal to`: Shows records where the field is equal to the specified value.
+- `is not equal to`: Shows records where the field isn't equal to the specified value.
+- `less than`: Shows records where the field is less than the specified value.
+- `less than or equal to`: Shows records where the field is less than or equal to the specified value.
+- `greater than`: Shows records where the field is greater than the specified value.
+- `greater than or equal to`: Shows records where the field is greater than or equal to the specified value.
+- `in`: Shows records where the field matches any of the specified values.
+- `not in`: Shows records where the field doesn't match any of the specified values.
+- `is null`: Shows records where the field is empty.
+- `is not null`: Shows records where the field isn't empty.
+
+### Rule Groups
+
+- **Group**: A group is a collection of rules combined by a logical operator (AND/OR). You can nest groups to create complex filters.
+
+### Creating a Filter
+
+1. Click on the `Filter` button to expand the filter menu.
+2. Select a logical operator (AND/OR) from the dropdown.
+3. Choose a field to filter by (e.g., `createdAt`).
+4. Select a rule (e.g., `is equal to`).
+5. Enter the required value or select from a calendar if it's a date field.
+6. To add another rule within the same logical condition, click the `+ Rule` button.
+7. To create a nested group of conditions, click the `+ Group` button.
+8. Apply the filter by clicking the `Apply filter` button.
+
+### Manually Editing Filters
+
+Click on **Edit Manually** to view and edit the filter in JSON format. You can then copy this JSON filter and use it in your table operations via code.
+
+## Operations on Tables - via the Interface
+
+### Add records to a table
+
+Once you've created a table, you can add records to it. To do this, click on the table in the explorer menu. You'll then see a list of all the records in the table. Click on the `Add Record` button to add a new record. You can then enter the values for each field in the record.
+
+### Update records in a table
+
+Double click on a table cell or press click it and press `Enter` to see an input that allows you to change the cell value. Once you are done, press `Enter` again or click away to save the new value.
+
+### Delete records from a table
+
+`Right Click` on the Record and select `Delete Record` to delete a record from a table.
+
+## Operations on Tables - via Cards
+
+Check out the [Table Cards documentation](/studio/concepts/cards/execute-code#table-cards) to learn more about operations with cards.
+
+## Operations on Tables - via Botpress Client
+
+You can also interact with tables using the Botpress Client. Here are some of the functions you can use to interact with tables:
+
+### List tables
+
+To list all the tables in the bot, use the `listTables` function. This function will return an array of all the tables in the bot.
+
+```javascript
+try {
+ const tables = await client.listTables({})
+ console.log('Tables:', tables)
+} catch (err) {
+ console.error('Error fetching tables', err)
+}
+```
+
+### Create Table Rows
+
+Execute the following query to create one or multiple rows. The response will include the inserted rows, along with any encountered errors or warnings during the operation (e.g., unrecognized fields)
+
+```javascript
+const { rows, errors, warnings } = await client.createTableRows({
+ table: 'Data1Table',
+ rows: [
+ {
+ name: 'test',
+ },
+ ],
+})
+```
+
+### Find & Filter Table Rows
+
+To find and filter rows in a table, use the `findTableRows` function. You can specify the limit (number of records to return) and the offset (number of rows to start from).
+
+```javascript
+const { rows, limit, offset, count } = await client.findTableRows({
+ table: 'Data1Table',
+ limit: 50,
+ offset: 0,
+ filter: {},
+ orderBy: 'row_id',
+ orderDirection: 'asc',
+})
+```
+
+Utilize filters to conduct more refined queries for specific rows, employing a MongoDB-like syntax. The query builder aids in understanding available operations and constructing the filter.
+
+```javascript
+const { rows, limit, offset, count } = await client.findTableRows({
+ table: 'Data1Table',
+ filter: {
+ // Retrieve rows where date is greater than a specific date
+ updatedAt: { gte: '2024-01-01' },
+ // Or more complex conditions, such as name starting with 'a' or 'b', or 'isActive' being true
+ $or: [{ name: { $regex: '^a' } }, { name: { $regex: '^b' } }, { isActive: true }],
+ },
+})
+```
+
+The "search" property allows for a partial text search across the table. The query returns multiple results, each accompanied by a similarity score to indicate relevance.
+
+```javascript
+const { rows, limit, offset, count } = await client.findTableRows({
+ table: 'Data1Table',
+ search: 'John Doe',
+})
+```
+
+### Projection & Aggregation
+
+Employ the group property for projections and aggregations. The following example demonstrates returning a single row with requested data.
+
+```javascript
+const { rows } = await client.findTableRows({
+ table: 'Data1Table',
+ group: {
+ id: 'count',
+ name: ['unique', 'count'], // will return a list of unique values & the total count
+ updatedAt: ['min', 'max'], // Retrieves the earliest and latest date
+ },
+})
+
+// Output variables are named after the field, suffixed with the operation
+const oldestChange = rows[0].updatedAtMin
+const mostRecentChange = rows[0].updatedAtMax
+const count = rows[0]['nameCount']
+const uniqueValues = rows[0]['nameUnique']
+```
+
+
+
+
+ |
+ Column
+ |
+
+
+ Type
+ |
+
+
+ Key
+ |
+
+
+ Count
+ |
+
+
+ Sum
+ |
+
+
+ Avg
+ |
+
+
+ Max
+ |
+
+
+ Min
+ |
+
+
+ Unique
+ |
+
+
+
+
+
+
+ |
+ id
+ |
+
+
+ number
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+ createdAt
+ |
+
+
+ date
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+ updatedAt
+ |
+
+
+ date
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+ name
+ |
+
+
+ string
+ |
+
+
+ ✔️
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+ ✔️
+ |
+
+
+
+
+
+**Key**: Projections are grouped by keys (ex: date)\
+**Count**: Returns the total number of non-null values\
+**sum**: Returns the sum of all values\
+**Avg**: Returns the average of all values\
+**Max**: Returns the maximum value\
+**Min**: Returns the minimum value\
+**Unique**: Returns a list of unique values
+
+Providing one or multiple keys yields more specific results.
+
+```javascript
+const { rows } = await client.findTableRows({
+ table: 'Data1Table',
+ group: {
+ someField: 'key', // Either provide a single operation
+ someNumber: ['avg', 'sum'], // Or multiple operations
+ },
+})
+
+// Returns multiple rows for each unique combination of keys
+const result = rows.map((row) => {
+ const { someFieldKey, someNumberAvg, someNumberSum } = row
+})
+```
+
+### Update Table Rows
+
+This operation updates rows based solely on their numeric IDs.
+
+```javascript
+const { rows, errors, warnings } = await client.updateTableRows({
+ table: 'Data1Table',
+ rows: [
+ {
+ id: 1,
+ name: 'test',
+ },
+ ],
+})
+```
+
+### Delete Table Rows
+
+Rows can be deleted from a table in three distinct manners, each mutually exclusive.
+
+By specifying row IDs\
+By applying a filter\
+By removing all rows
+
+```javascript
+const { deletedRows } = await client.deleteTableRows({
+ table: 'Data1Table',
+ // Specify a list of IDs
+ ids: [1, 2, 3],
+ // Or use a filter (caution: all rows matching the filter will be deleted. It's advisable to first test with the findTableRows query)
+ filter: { name: 'John Doe' },
+ // Deletes every row within this table, irreversible action
+ deleteAllRows: true,
+})
+```
+
+### Upsert Table Rows
+
+The upsert operation is a combination of insert or update, allowing you to insert new rows or update existing ones. The operation is based on the row's `keyColumn`.
+
+`keyColumn`: The column used to identify the row. This column must be unique. Failure occurs if more than one row is found for the same key.
+
+```javascript
+const { rows, inserted, updated, errors, warnings } = await client.upsertTableRows({
+ table: 'Data1Table',
+ keyColumn: 'email',
+ rows: [
+ {
+ email: 'hello@world.com', // will update this row, or create a new one if not found
+ name: 'test',
+ },
+ ],
+})
+```
+
+### Create Table
+
+To create a table, simply provide a name and a schema. The naming convention follows the same rules as those applied within the studio. Initially, the schema can be empty and populated or modified later. The schema accepts either an example object, from which it will infer the structure, or a directly provided JSON schema.
+
+```javascript
+const { table } = await client.createTable({
+ name: 'Data1Table',
+ schema: {
+ name: 'test',
+ },
+})
+```
+
+Example using a JSON schema. A field marked as 'searchable' will be indexed, enhancing its availability for search queries. Note, 'index' is a system-managed, read-only attribute.
+
+```javascript
+const { table } = await client.createTable({
+ name: 'Data1Table',
+ schema: {
+ type: 'object',
+ 'x-zui': {},
+ properties: {
+ name: {
+ type: 'string',
+ 'x-zui': {
+ index: 0,
+ searchable: true,
+ },
+ nullable: true,
+ },
+ },
+ additionalProperties: true,
+ },
+})
+```
+
+### Update Table
+
+You can update a table's name, schema, or both. Providing only one of these attributes is also permissible. Should you alter the type of an existing column, be advised that all its entries will default to NULL.
+
+#### Adding a new field
+
+```javascript
+const { table } = await client.updateTable({
+ table: 'Data1Table',
+ schema: {
+ myNewField: 'abc', // Direct value assignment
+ // Or specify with a JSON schema
+ myNewField: { type: 'string' },
+ },
+})
+```
+
+#### Removing an existing field:
+
+```javascript
+const { table } = await client.updateTable({
+ table: 'Data1Table',
+ schema: {
+ myOldField: null, // Field removal
+ },
+})
+```
+
+#### Renaming the table
+
+A table name must end with "Table".
+
+```javascript
+await client.updateTable({ table: 'Data1Table', name: 'myNewTable' })
+```
+
+#### Rename Table Column
+
+To rename a table column, specify both the current and new names. The column's data type and attributes will remain unchanged.
+
+```javascript
+const { table } = await client.renameTableColumn({
+ table: 'Data1Table',
+ name: 'My Old Column Name',
+ newName: 'New Column Name',
+})
+```
+
+### Get Table
+
+To retrieve a table's schema, use the `getTable` function. This will return the table definition, along with the total number of rows, number of stale rows and number of indexing rows.
+
+```javascript
+const { table, indexing, rows, stale } = await client.getTable({ table: 'Data1Table' })
+```
+
+### Delete Table
+
+To delete a table, use the `deleteTable` function. This will permanently remove the table and all its records.
+
+```javascript
+const { table } = await client.deleteTable({ table: 'Data1Table' })
+```
+
+## Operations on Tables - via Code
+
+
+
+### Create record
+
+To create a new record in a table, use the `createRecord` function. You can specify the values for each field in the record. This function can be particularly useful when you need to store new information, such as a new user's details or a newly completed transaction.
+
+
+
+```javascript
+// Create a record in the table
+await Data1Table.createRecord({ Age: 25, Name: 'Tom', Occupation: 'Student' })
+```
+
+### Create records
+
+To create multiple records in a table, use the `createRecords` function. You can specify the values for each field in the record. Useful for creating multiple records at once.
+
+
+
+```javascript
+// Creating two records in the table
+await Data1Table.createRecords([
+ { Name: 'Tom', Age: 25, Occupation: 'Student', 'Is Friendly': true },
+ { Name: 'Didier', Age: 54, Occupation: 'Pilot', 'Is Friendly': true },
+])
+```
+
+### Delete record
+
+To delete a record in a table, use the `deleteRecord` function. You need to specify the record ID of the record you want to delete.
+
+
+
+```javascript
+// Delete a record in the table at record ID 7
+await Data1Table.deleteRecord(7)
+```
+
+### Delete records
+
+To delete multiple records in a table, use the `deleteRecords` function. You need to specify the record IDs of the records you want to delete in an array.
+
+
+
+```javascript
+// Delete records in the table at record IDs 7, 8, 9
+await Data1Table.deleteRecords([7, 8, 9])
+```
+
+### Find records
+
+To find records in a table, use the `findRecords` function. You can add filters, just query everything or search using semantic search (like a Google Search!).
+
+#### Basic usage and pagination
+
+To retrieve data from a table in Botpress, you can use the `findRecords` function. This function allows you to specify the limit (number of records to return) and the offset (number of rows to start from).
+
+For instance, if you want the first 10 records, you can set the limit to 10 and the offset to 0. To fetch the next 10 records, you can set the limit to 10 and the offset to 10.
+
+To determine if there are more records available, you can check the length of the array returned. If the length is greater than 0, it indicates the presence of additional records.
+
+Here's an example:
+
+```javascript
+const limit = 10
+const startRow = 0
+
+workflow.records = await DataTable1.findRecords({
+ limit,
+ offset: startRow,
+})
+
+// Checking the second page
+const secondPage = await Data1Table.findRecords({
+ limit,
+ filter: AI`everything`,
+ offset: startRow + limit,
+})
+
+workflow.hasNextPage = secondPage.length > 0 // This flag can be consumed in your bot Workflow to handle pagination
+```
+
+You can apply a similar approach to determine if there are previous pages as well.
+
+#### Searching fields with natural language
+
+To perform a traditional search, use the search parameter when calling the DataTable1.findRecords() function in Botpress. Here is an example:
+
+```javascript
+workflow.records = await DataTable1.findRecords({ search: 'red velvet chairs' })
+```
+
+You can pass variables like event.preview to the search parameter to search for user input or any other variable. This allows you to pre-process the user's input before performing the search.
+
+#### Filtering results
+
+You can filter results using filters. Similar to MongoDB, this code provides methods to filter results. The filtering mechanism can be divided into two main categories: Primitive and Logical.
+
+Don't want to deal with code? Skip to the [next section](#using-ai-to-generate-filters) for AI generated filters.
+
+#### **Primitive Filter**
+
+Primitive filters are easy and simple to use, allowing you to match the exact values you are looking for. Here are some of the primitives you can use:
+
+- `$eq`: Matches values that are equal to a specified value.
+
+ ```json
+ { "name": { "$eq": "John" } }
+ ```
+
+- `$gt`: Matches values that are greater than a specified value.
+
+ ```json
+ { "age": { "$gt": 20 } }
+ ```
+
+- `$gte`: Matches values that are greater than or equal to a specified value.
+
+ ```json
+ { "age": { "$gte": 20 } }
+ ```
+
+- `$lt`: Matches values that are less than a specified value.
+
+ ```json
+ { "age": { "$lt": 20 } }
+ ```
+
+- `$lte`: Matches values that are less than or equal to a specified value.
+
+ ```json
+ { "age": { "$lte": 20 } }
+ ```
+
+- `$ne`: Matches all values that aren't equal to a specified value.
+
+ ```json
+ { "name": { "$ne": "John" } }
+ ```
+
+- `$in`: Matches any of the values specified in an array.
+
+ ```json
+ { "name": { "$in": ["Alice", "Bob", "John"] } }
+ ```
+
+- `$nin`: Matches none of the values specified in an array.
+
+ ```json
+ { "name": { "$nin": ["Alice", "Bob", "John"] } }
+ ```
+
+- `$exists`: Matches documents that have the specified field.
+
+ ```json
+ { "name": { "$exists": true } }
+ ```
+
+- `$mod`: Performs modulo operation on the value of field and matches documents where field % divisor equals the specified remainder.
+
+ ```json
+ { "qty": { "$mod": [4, 0] } }
+ ```
+
+- `$size`: Matches any document where an array field contains a specified number of elements.
+
+ ```json
+ { "tags": { "$size": 3 } }
+ ```
+
+- `$regex`: Provides regular expression capabilities for pattern matching strings in queries. It uses a placeholder to prevent SQL injections.
+
+ ```json
+ { "name": { "$regex": "[a-z]" } }
+ ```
+
+- `$options`: Modifies the `$regex` operator to enable options. Currently, there are two options, 'i' for case-insensitive and 'c' for case-sensitive.
+
+ ```json
+ { "name": { "$regex": "[a-z]", "$options": 'i' } } // case-insensitive
+
+ { "name": { "$regex": "[a-z]", "$options": 'c' } } // case-sensitive
+ ```
+
+#### **Logical Filter**
+
+Logical operators allow you to connect more filtering clauses.
+
+- `$and`: Joins query clauses with a logical AND. Returns all documents that match the conditions of both clauses.
+
+ ```json
+ { "$and": [{ "price": { "$ne": 1.99 } }, { "price": { "$exists": true } }] }
+ ```
+
+- `$or`: Joins query clauses with a logical OR. Returns all documents that match the conditions of either clause.
+
+ ```json
+ { "$or": [{ "price": { "$eq": 1.99 } }, { "price": { "$exists": false } }] }
+ ```
+
+- `$not`: Inverts the effect of a query expression and returns documents that don't match the query expression.
+
+ ```json
+ { "$not": { "price": { "$eq": 1.99 } } }
+ ```
+
+Please note that these filters and operators can be used together to create complex queries to exactly fit your needs. You can also nest filters like so :
+
+```javascript
+{
+ "$and": [
+ { "price": { "$lte": 19.99 }},
+ { "$or": [
+ {"category": { "$eq": "Shoes" }},
+ {"category": { "$eq": "Hats"}}
+ ]
+ }
+ ]
+ }
+```
+
+If you have a column of type object, you can also use operators on nested paths:
+
+```json
+{
+ "customer.name": { "$regex": "[a-z]" },
+ "customer.age": { "$gte": 18 }
+}
+```
+
+#### Using AI to generate filters
+
+Thankfully, Botpress comes with artificial intelligence (AI) capabilities when it comes to filtering records. This means you can provide a human-like query, and the AI will intelligently decipher it and create the right filters for your query.
+
+This can significantly simplify the construction of complex queries and reduce the likelihood of human errors in the process.
+
+```javascript
+const leads = await LeadsTable.findRecords({
+ filter: AI`works either at ${workflow.company} OR is not in IT`,
+ limit: 10,
+ offset: 0,
+})
+```
+
+The query is written inside the backticks (\`) that come after \`filter: AI\`. The AI expects a query string, and that's why backticks are used.
+
+#### Re-using filters (selectors)
+
+Selectors are filters that you can re-use. They don't have to be written again and again.
+
+For example, you might use the query selector "People with age greater than 18" to find all users who are above 18.
+
+1. Create a query selector in the table and give it a name. (for example: adults)
+2. Add query as `People with age greater than 18`
+3. use below code to find records and save it in a variable called `adults`
+
+
+
+```javascript
+// Find records in the table
+const data = await Data1Table.findRecords({ selectorName: 'adults' })
+workflow.adults = data
+```
+
+#### Difference between search and AI filters
+
+A standard `Search` in Botpress is employed to identify specific strings like a user's name. It gives precision-based results by matching specific sets of characters.
+
+On the other hand, an `AI Filter` broadens the scope and is used primarily for filtering results rather than explicitly searching them. It helps you track down users based on certain criteria, such as age above 25.
+
+Although the AI Filter isn't primarily designed for exact string hunting, it's flexible enough to allow it. For instance, you could use it to filter results for `Canada` as a country.
+
+### Get record
+
+You can use the `getRecord` function to retrieve a specific record from a table based on a unique identifier. For example, you might use the `getRecord` function to retrieve a user's profile information based on their unique user ID.
+
+
+
+```javascript
+// The record ID is 1 and User is the variable name
+const data = await Data1Table.getRecord(1)
+workflow.User = data
+```
+
+### Update record
+
+You can use the `updateRecord` function to modify a specific record in a table. This will be useful when you need to update a specific field in the record. For example, you might use this function to update a user's profile information or to update the status of a transaction.
+
+```javascript
+// Update at record ID 8's Age to 45
+await Data1Table.updateRecord(8, { Age: 45 })
+```
+
+### Upsert record
+
+The `upsertRecords` function allows you to update or create records in a table in a single operation. It's useful for any situation where you need to update or insert data into a table without having to worry about whether the rows already exist.
+
+**Example:**
+
+```javascript
+// Update the name and address of the records with IDs 1 and 2.
+await CustomersTable.upsertRecords('id', [
+ { id: 1, name: 'John Doe', address: '123 Main Street' },
+ { id: 2, name: 'Jane Doe', address: '456 Elm Street' },
+])
+```
+
+This code will upsert the records into the CustomersTable. If the records with IDs 1 and 2 already exist in the table, the function will update the existing rows with the new name and address values. If the records with IDs 1 and 2 don't already exist in the table, the function will insert new rows into the table with the new name and address values.
+
+## Computed Columns
+
+Columns can be marked as "Computed" which allows the
bot builder to observe changes in tables and generate computed values. This includes leveraging AI, as well as running code. This can be useful for a wide variety of use cases such as CRM enrichment, sentiment analysis, classification.
+
+To use computed columns, simply create a column and toggle the **Computed** field as shown below.
+
+
+
+### Selecting the basis of computation
+
+To compute columns, you must select what information you will base your computed columns on. To do so, click the **Dependencies** field and select all column names that you will use.
+
+
+
+In the above example, we selected a column called **number**.
+
+### AI-based computed columns
+
+You can perform AI text generation tasks by filling the prompt and including rows like this \{\{propertyName}}.
+
+```
+Come up with the title for a story like the three little pigs for the number {{number}}
+```
+
+In the above example, for the number 3, you might get "The Three Clever Squirrels" as a value in the cell.
+
+### Code-based computed columns
+
+To run arbitrary code, select the **Execute code** tab. Then, click **Edit Code**.
+
+
+
+You will see a window with a code editor.
+
+
+
+Simply add your code above. The proper syntax for accessing columns you've identified as dependencies is row[propertyName], and the displayed cell value is what's returned by this function. You can call asynchronous functions within the function, and have the **Axios** library available to perform HTTP requests.
+
+For instance, the following code will return the Fibonacci number of the row value for the column **number**.
+
+```js
+function fibonacci(n) {
+ if (n <= 1) {
+ return n
+ }
+ return fibonacci(n - 1) + fibonacci(n - 2)
+}
+
+if (!row.number) {
+ return 0
+}
+
+return fibonacci(row.number)
+```
+
+There is currently an execution timeout of two minutes these.
+
+### Updating computed values
+
+To ensure computed values are always kept up to date, we recommend **Auto-compute** be toggled on.
+
+
+
+If you don't have **Auto-compute** enabled, a grey icon will appear next to stale table cells.
+
+
+
+To update the stale data, simply re-activate **Auto-compute**.
+
+## Importing and Exporting
+
+### Import a Table
+
+You can import a table from a CSV file. Click on the `Import Table` button above the table and select the CSV file you want to import. Botpress will automatically detect the column names and types from the CSV file and create the table structure for you.
+
+### Export a Table
+
+Click on the `Export Table` button to export the table. This will download the table as a CSV file to your computer.
+
+
+Reminder
+
+Don't edit the CSV file directly to avoid data loss and import errors. Instead, make the changes in Botpress Studio and then export the updated table again.
+
+
+
+
+Note
+
+When you export a bot, the tables are exported as well so there is no need to export them separately unless you want to use them in another bot.
+
+
diff --git a/src/content/docs/studio/concepts/triggers.mdx b/src/content/docs/studio/concepts/triggers.mdx
new file mode 100644
index 0000000..c1d6d3e
--- /dev/null
+++ b/src/content/docs/studio/concepts/triggers.mdx
@@ -0,0 +1,144 @@
+---
+title: Triggers
+icon: Play
+---
+
+import Step from '@/components/Step.astro'
+import Steps from '@/components/Steps.astro'
+import { Tip, Note, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+Triggers are a special kind of [Node](/studio/concepts/nodes/introduction) that only **execute when a certain event occurs**. You can recognize Triggers by their distinctive purple colour:
+
+

+
+Triggers are useful if you want your bot to:
+
+- [Send a welcome message](#conversation-started)
+- [Do something at a specific date/time](#fixed-schedule)
+- [Respond to changes on your website](#custom-trigger)
+
+
+ ### Limitations
+
+ - Triggers won't work in the Studio's emulator, even when the event they're expecting occurs. Instead, you can [test them](#test-a-trigger) before publishing.
+ - Triggers won't work while your bot is waiting for user input from a [Capture Information](/studio/concepts/cards/capture-information) Card.
+
+
+
+## Triggers vs. Nodes
+
+Triggers are different from regular Nodes in a few ways:
+
+- You **can't transition** from a regular Node to a Trigger. Any Triggers in your Workflow will only execute when the event they listen for occurs.
+ - Unlike other Nodes, **you can't add or remove [Cards](/studio/concepts/cards/introduction)** from a Trigger. Each Trigger is built around a single Card that determines when it executes.
+
+## Add a Trigger
+
+To add a Trigger, just right-click anywhere in a Workflow:
+
+

+
+## Test a Trigger
+
+Triggers won't work in the Studio's emulator, even when the event they're expecting occurs. Instead, you can use a previous event to test your Trigger.
+
+For example, to test the [Conversation Started](#conversation-started) Trigger:
+
+
+
+ Right-click anywhere in your Workflow. Select **Trigger**, then **Conversation Started**:
+
+
+ 
+
+
+
+ Select **Test** in the bottom-left corner of the Trigger:
+
+
+ 
+
+
+ Then, select **Show last received events**. This will display a list of past events that would set off your Trigger:
+
+
+ 
+
+
+ For the **Conversation Started** Trigger, each of these is a `conversationStarted` event, which fires every time a user starts a new conversation with your bot.
+
+ You can use any one of these events as a dummy event to test your Trigger. Just pick one and select **Add as Test**. Then, select **Save**.
+
+
+ If there are no events available to choose, make sure your bot is published and that the event your Trigger is listening for has occurred at least once before.
+
+
+
+
+ Now, you should see the name of the event in the Trigger:
+
+
+ 
+
+
+ Just press the play icon to fire the Trigger. Any logic you have connected to the Trigger will execute in the emulator:
+
+
+ 
+
+
+
+
+
+## Webchat Triggers
+
+Studio comes with some built-in Triggers that let your bot react to certain events in Webchat:
+
+### Conversation Started
+
+
+ For a step-by-step guide to the **Conversation Started** Trigger, check out the [Webchat
+ documentation](/webchat/interact/start-trigger).
+
+
+The **Conversation Started** Trigger only executes when a user starts a new conversation in Webchat. You can use it to make your bot do something as soon as a user starts a new conversation.
+
+For example, sending a welcome message:
+
+

+
+### Custom Trigger
+
+
+ For a step-by-step guide to using **Custom Triggers**, check out the [Webchat
+ documentation](/webchat/interact/send-custom-events/to-webchat).
+
+
+You can use **Custom Triggers** to make Webchat react to custom events from your website. This is useful if you want to make your bot more responsive to the rest of your user experience.
+
+For example, if you want your bot to respond when a user clicks a button:
+
+

+
+## Fixed Schedule
+
+
+ Check out our step-by-step guide on [using the Fixed Schedule Trigger](/studio/concepts/cards/fixed-schedule).
+
+
+You can use the **Fixed Schedule** Trigger to execute some part of your Workflow at a specific time. This is useful if you want to send reminders, notifications, or other time-sensitive messages to users.
+
+## Integrations
+
+
Check out the [integrations section](/integrations/) for information about integration-specific Triggers.
+
+Some integrations include their own Triggers. When you install an integration that has Triggers, they'll become available in the Triggers menu.
+
+For example, the [Zendesk integration](/integrations/integration-guides/zendesk) comes with two Triggers—**Article Published** and **Article Unpublished**:
+
+
+
+
+
+
diff --git a/src/content/docs/studio/concepts/variables/assets/assign-value.png b/src/content/docs/studio/concepts/variables/assets/assign-value.png
new file mode 100644
index 0000000..f1d015c
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/assign-value.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/create-variable.png b/src/content/docs/studio/concepts/variables/assets/create-variable.png
new file mode 100644
index 0000000..ac07b73
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/create-variable.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/input-var-field-dark.png b/src/content/docs/studio/concepts/variables/assets/input-var-field-dark.png
new file mode 100644
index 0000000..ed3abd4
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/input-var-field-dark.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/input-var-field.png b/src/content/docs/studio/concepts/variables/assets/input-var-field.png
new file mode 100644
index 0000000..1c66b18
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/input-var-field.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/read-variable-dark.png b/src/content/docs/studio/concepts/variables/assets/read-variable-dark.png
new file mode 100644
index 0000000..5ed07bd
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/read-variable-dark.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/read-variable.png b/src/content/docs/studio/concepts/variables/assets/read-variable.png
new file mode 100644
index 0000000..6620a88
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/read-variable.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/toggle-input-variable-dark.png b/src/content/docs/studio/concepts/variables/assets/toggle-input-variable-dark.png
new file mode 100644
index 0000000..d1946a1
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/toggle-input-variable-dark.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/toggle-input-variable.png b/src/content/docs/studio/concepts/variables/assets/toggle-input-variable.png
new file mode 100644
index 0000000..d87d886
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/toggle-input-variable.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/toggle-output-variable-dark.png b/src/content/docs/studio/concepts/variables/assets/toggle-output-variable-dark.png
new file mode 100644
index 0000000..214113a
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/toggle-output-variable-dark.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/toggle-output-variable.png b/src/content/docs/studio/concepts/variables/assets/toggle-output-variable.png
new file mode 100644
index 0000000..be6f9c1
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/toggle-output-variable.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/workflow-card-dark.png b/src/content/docs/studio/concepts/variables/assets/workflow-card-dark.png
new file mode 100644
index 0000000..638f58a
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/workflow-card-dark.png differ
diff --git a/src/content/docs/studio/concepts/variables/assets/workflow-card.png b/src/content/docs/studio/concepts/variables/assets/workflow-card.png
new file mode 100644
index 0000000..7fedbaf
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/assets/workflow-card.png differ
diff --git a/src/content/docs/studio/concepts/variables/built-in.mdx b/src/content/docs/studio/concepts/variables/built-in.mdx
new file mode 100644
index 0000000..27e7b20
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/built-in.mdx
@@ -0,0 +1,22 @@
+---
+title: Built-in variables
+---
+
+Botpress provides several **built-in variables** that contain useful information about the current state of your bot. You don't need to create these variables yourself—you can just read them whenever you need them.
+
+Here's a list of all the built-in variables in Botpress:
+
+| Path | Type | Description |
+| ------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `event.preview` | Event | The last message sent by the user. It will be replaced every time there is a new message. |
+| `conversation.SummaryAgent.summary` | Agent | Summary of the conversation created by the [Summary Agent](/studio/concepts/agents/summary-agent). It's an explanation of what happened. |
+| `conversation.SummaryAgent.transcript` | Agent | Transcript of the conversation going back a certain amount of turns. |
+| `turn.KnowledgeAgent.answer` | Agent | The answer provided by the [Knowledge Agent](/studio/concepts/agents/knowledge-agent) |
+| `turn.KnowledgeAgent.responded` | Agent | Whether the Knowledge Agent has responded automatically to a user question. Its value will be `true` or `false` |
+| `turn.KnowledgeAgent?.answer?.length` | Agent | The amount of characters in the Knowledge answer. Use this in an [Expression](/studio/concepts/cards/flow-logic#expression) to check if there is an answer in the KB. Optionally add `!` to start of the code in order to check if there WASN'T an answer. |
+| `turn.KnowledgeAgent.citations` | Agent | A list of citations for the Knowledge answer. |
+| `user.TranslatorAgent.language` | Agent | The current user language code in ISO 639-1 format. [More about the Translator Agent](/studio/concepts/agents/translator-agent) |
+| `user.TranslatorAgent.language = 'en'` | Agent | This code snippet set's the user language to English. Replace with any language code in the ISO 639-1 format |
+| `event.kb.results.map((a) => a.dsFriendlyName + '\n' + a.content).join('\n\n')` | Event | This code snippet returns the raw content that generated the final Knowledge answer. |
+| `event.tags.conversation['whatsapp:userPhone']` | Integration | The user's phone number on WhatsApp. Includes the international code. |
+| `event.tags.conversation['whatsapp:phoneNumberId']` | Integration | The phone number ID of the bot on WhatsApp. |
diff --git a/src/content/docs/studio/concepts/variables/in-code.mdx b/src/content/docs/studio/concepts/variables/in-code.mdx
new file mode 100644
index 0000000..7d5984e
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/in-code.mdx
@@ -0,0 +1,96 @@
+---
+title: Use variables in code
+---
+
+import { Tip } from '@/components/callouts'
+
+If you need more flexibility in how you handle information in Botpress Studio, you can use variables in code (for example, in an [Execute Code](/studio/concepts/cards/execute-code) Card).
+
+
Variables in code follow the pattern `variabletype.variablename`.
+
+Here are a few examples of how you might use variables in code:
+
+## Assign a value to a variable
+
+This is typically how you'd initialize a variable or change its value.
+
+```javascript
+workflow.orderNumber = 12345
+conversation.cartTotal = 59.99
+user.lastName = 'Smith'
+bot.version = '1.2.3'
+env.databaseURL = 'https://example.com/db'
+```
+
+## Use variables in conditional statements
+
+This checks the value of a variable and executes code accordingly.
+
+```javascript
+if (user.firstName === 'John') {
+ console.log('Hello John!')
+} else {
+ console.log('Welcome, user!')
+}
+```
+
+## Use variables in functions
+
+Here, you might pass a variable as a function argument or use it inside a function.
+
+```javascript
+function greetUser(firstName) {
+ console.log('Hello, ' + firstName + '!')
+}
+
+greetUser(user.firstName)
+```
+
+## Combine variables
+
+You might want to combine or concatenate variables.
+
+```javascript
+var fullName = user.firstName + ' ' + user.lastName
+
+// or
+
+var welcomeMessage = 'Hello, ' + user.firstName + ' ' + user.lastName + '!'
+```
+
+## Check variable types
+
+Botpress might throw an error if types don't match. To avoid this, you can use type checking before assigning values.
+
+```javascript
+if (typeof workflow.userAcctId === 'number') {
+ workflow.userAcctId = 67890
+} else {
+ console.error('Invalid type for userAcctId!')
+}
+```
+
+## Use variables with external APIs
+
+If your bot interacts with external services, you might use an environment variable to store an API key:
+
+````javascript
+const apiKey = env.API_KEY
+const apiUrl = env.API_URL
+
+const config = {
+ headers: {
+ Authorization: `Bearer ${apiKey}`,
+ },
+}
+
+const response = await axios.get(apiUrl, config)
+const data = response.data
+
+// Process the data as needed
+// ...
+
+// Example: Log the response data
+console.log(data)
+``` |
+````
diff --git a/src/content/docs/studio/concepts/variables/overview.mdx b/src/content/docs/studio/concepts/variables/overview.mdx
new file mode 100644
index 0000000..81f0cab
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/overview.mdx
@@ -0,0 +1,192 @@
+---
+title: Variables
+description: Containers for storing and reusing information in Botpress Studio.
+sidebarTitle: Overview
+---
+
+import { Tip, Note } from '@/components/callouts'
+import CardGroup from '@/components/CardGroup.astro'
+import Card from '@/components/Card.astro'
+import Frame from '@/components/Frame.astro'
+
+Variables let you **store information** from somewhere in Botpress Studio and **reuse it somewhere else**.
+
+
+ Think of a variable like an **empty box**. You can fill it with any kind of information you want—like a name, a
+ number, or a preference—and put it away for safekeeping. Then, when your bot needs that information again, it can open
+ the box and access what's inside.
+
+
+## Variable scopes
+
+You can use different types of variables to **scope** the information you store. This gives you control over where your bot can access a piece of information. For example, you might want some information to:
+
+- [Follow a user across all their conversations](/studio/concepts/variables/scopes/user) (for example, their name and address)
+- [Persist only throughout a single conversation](/studio/concepts/variables/scopes/conversation) (for example, items in a virtual cart)
+- [Be safely accessible across all your bot's activity](/studio/concepts/variables/scopes/configuration) (for example, API tokens and secrets)
+
+Select any variable scope below to learn more about it:
+
+
+
+ Only available within the current Workflow
+
+
+ Available for all conversations with a user
+
+
+ Only available within the current conversation
+
+
+ Available throughout all your bot's activity
+
+
+ Available throughout all your bot's activity, but can't be displayed to users
+
+
+
+## Create a variable
+
+
+ Configuration variables have a different setup process. Check out the [configuration
+ variables](/studio/concepts/variables/scopes/configuration) page for more information.
+
+
+Before you can store information in a variable, you need to create it:
+
+1. Open any Workflow.
+2. Select **+** in the **Variables** section at the bottom of the left navigation bar.
+3. Choose a [Scope](#variable-scopes), [Type](#data-types-for-variables) and **Name** for your variable:
+
+

+
+
+ By default, variables are empty when created. However, you can create them with a default value if you prefer—just
+ specify a **Default Value** in the **Additional Settings** menu.
+
+
+### Assign a value to your variable
+
+A freshly created variable is like an empty box—you need put something inside it before you can use it. This is called **assigning a value** to your variable.
+
+Studio will usually indicate where you have the option to assign a value to a variable.. For example, in a [Capture Information](/studio/concepts/cards/capture-information) Card:
+
+

+
+
+ If you want more control over when and how you assign a value to a variable, you can [use code
+ instead](/studio/concepts/variables/in-code).
+
+
+### Read your variable
+
+When you need to access the information stored in a variable, you can **read** it. This is like opening the box and looking at what's inside.
+
+Each variable scope is read differently. Check out the [section for your variable's scope](#variable-scopes) for more information.
+
+## Data types for variables
+
+Botpress variables are **typed**, meaning they're limited in what data they can hold. These data types are important to:
+
+- Ensure the code behind Botpress runs smoothly
+- Help AI tasks generate better results
+
+Here are the different data types available for Botpress variables:
+
+
+
+
+ |
+ Type
+ |
+
+
+ Description
+ |
+
+
+
+
+
+
+ |
+ String
+ |
+
+
+ Values that are treated as text. Strings can contain any amount of letters, numbers, or special characters. Example uses: Storing a user's name, storing an AI task's generated message.
+ |
+
+
+
+ |
+ Boolean
+ |
+
+
+ Variables can be true or false, with a lowercase 't' or 'f'. Example uses: Storing if a user is a returning customer, storing whether the bot has greeted the user or not
+ |
+
+
+
+ |
+ Number
+ |
+
+
+ Variables that are numeric, either with or without decimal places. Example uses: Storing a user's phone number, storing an address's area code
+ |
+
+
+
+ |
+ Date
+ |
+
+
+ Variables that are a single date or date and time. Botpress uses ISO 8601 date/time format, such as `20220921T10:34:14` for `21 September 2023 at 10:34 AM` (with 14 seconds). Example uses: Storing when the user starts a chat, storing a user's appointment date
+ |
+
+
+
+ |
+ Object
+ |
+
+
+ Variable that's a collection of key-value pairs. Useful when dealing with code and written like `{key: value}`. Example uses: Storing a user's profile, storing the results of an API call
+ |
+
+
+
+ |
+ Array
+ |
+
+
+ Variable that's a collection of other, similar variables. Arrays can contain strings, like `[“a”, “b”, “c”]`, or Objects like `[{key:value},{key:value}]`. Example uses: Storing a user's past messages, storing options for the user to choose from
+ |
+
+
+
+ |
+ Enum
+ |
+
+
+ Variable that can be one of a set number of choices. Example uses: Storing days of the week, storing items available from a food menu
+ |
+
+
+
+ |
+ Pattern
+ |
+
+
+ Variable that uses Regular Expressions/Regex to store a special pattern. This pattern can match certain words or numbers. Example uses: Storing account numbers, storing flight numbers
+ |
+
+
+
+
diff --git a/src/content/docs/studio/concepts/variables/pass-between-workflows.mdx b/src/content/docs/studio/concepts/variables/pass-between-workflows.mdx
new file mode 100644
index 0000000..96c5c64
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/pass-between-workflows.mdx
@@ -0,0 +1,152 @@
+---
+title: Pass variables between Workflows
+sidebarTitle: Pass between Workflows
+---
+
+import { Picture } from 'astro:assets'
+import inputVarFieldDarkImg from './assets/input-var-field-dark.png'
+import inputVarFieldImg from './assets/input-var-field.png'
+import readVariableDarkImg from './assets/read-variable-dark.png'
+import readVariableImg from './assets/read-variable.png'
+import toggleInputVariableDarkImg from './assets/toggle-input-variable-dark.png'
+import toggleInputVariableImg from './assets/toggle-input-variable.png'
+import toggleOutputVariableDarkImg from './assets/toggle-output-variable-dark.png'
+import toggleOutputVariableImg from './assets/toggle-output-variable.png'
+import workflowCardDarkImg from './assets/workflow-card-dark.png'
+import workflowCardImg from './assets/workflow-card.png'
+
+import Step from '@/components/Step.astro'
+import Steps from '@/components/Steps.astro'
+import { Note, Check } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+You can pass variables between Workflows. This is useful if you want to use a previously created variable within the scope of a single Workflow. For example:
+
+- You want to collect user information in one Workflow, then validate it in a sub-Workflow.
+- You have a Workflow that stores items in a virtual shopping cart, and you want to process payment for those items in a sub-Workflow.
+- You have some condition in one Workflow, and you want a sub-Workflow to behave differently based on that condition.
+
+## From a parent Workflow to a sub-Workflow
+
+
+
+ 1. In your sub-Workflow (the one you want to pass the variable to), [create a new Workflow variable](/studio/concepts/variables/overview/#create-a-variable).
+
+
+ You can pass any kind of variable from your parent Workflow, but your sub-Workflow needs to treat it as a Workflow variable.
+
+
+ 2. Select your sub-Workflow's [Entry Node](/studio/concepts/nodes/introduction#entry-node).
+ 3. Under **Toggle Variables**, select the variable you just created:
+
+
+
+
+
+
+ This tells the parent Workflow that your sub-Workflow is expecting some input.
+
+
+
+ In your parent Workflow, select the Card that transitions to the sub-Workflow. It should display the input variable you just created:
+
+
+
+
+
+
+ You can manually enter a value to pass to the sub-Workflow, or use a previously created variable from your parent Workflow.
+
+
+ Now, whatever value you pass from your parent Workflow will be available in your sub-Workflow as a Workflow variable.
+
+
+
+
+
+## From a sub-Workflow to a parent Workflow
+
+
+
+ 1. Select your sub-Workflow's [Exit Node](/studio/concepts/nodes/introduction/#exit-node).
+ 2. Under **Toggle Variables**, select the variable you want to pass:
+
+
+
+
+
+
+ This tells the parent Workflow to expect some output from the sub-Workflow.
+
+
+ You can only pass Workflow variables from a sub-Workflow to a parent Workflow.
+
+
+
+
+ 1. In the parent Workflow, select the Card that transitions to the sub-Workflow:
+
+
+
+
+
+
+ 2. Make sure the **Exit Nodes** option is selected.
+
+
+
+ To access the sub-Workflow's output variable from within the parent Workflow, read:
+
+ `workflow..`
+
+
+
+
+
+
+
+ Your parent Workflow now has access to its sub-Workflow's variable.
+
+
+
+
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/access-config-var.png b/src/content/docs/studio/concepts/variables/scopes/assets/access-config-var.png
new file mode 100644
index 0000000..d690cf8
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/access-config-var.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/bot-variable-example.png b/src/content/docs/studio/concepts/variables/scopes/assets/bot-variable-example.png
new file mode 100644
index 0000000..469a1b4
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/bot-variable-example.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/configuration-fields.png b/src/content/docs/studio/concepts/variables/scopes/assets/configuration-fields.png
new file mode 100644
index 0000000..c8678b5
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/configuration-fields.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/configuration-variables.png b/src/content/docs/studio/concepts/variables/scopes/assets/configuration-variables.png
new file mode 100644
index 0000000..52d6fc5
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/configuration-variables.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/conversation-variable-example.png b/src/content/docs/studio/concepts/variables/scopes/assets/conversation-variable-example.png
new file mode 100644
index 0000000..a725d10
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/conversation-variable-example.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/user-variable-example.png b/src/content/docs/studio/concepts/variables/scopes/assets/user-variable-example.png
new file mode 100644
index 0000000..509c8e6
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/user-variable-example.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/assets/workflow-variable-example.png b/src/content/docs/studio/concepts/variables/scopes/assets/workflow-variable-example.png
new file mode 100644
index 0000000..81b3de3
Binary files /dev/null and b/src/content/docs/studio/concepts/variables/scopes/assets/workflow-variable-example.png differ
diff --git a/src/content/docs/studio/concepts/variables/scopes/bot.mdx b/src/content/docs/studio/concepts/variables/scopes/bot.mdx
new file mode 100644
index 0000000..7f511df
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/scopes/bot.mdx
@@ -0,0 +1,32 @@
+---
+title: Bot variables
+---
+
+import { Tip, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+Bot variables let you store and reuse information **throughout your entire bot**.
+
+Any information you assign to a bot variable will be accessible across all Workflows and conversations. This makes bot variables useful for storing global information about your bot, like:
+
+- Your bot's name
+- Your bot's version number
+- Endpoints for your bot's API calls
+
+
+ Bot variables aren't encrypted or stored securely. This means **an Autonomous Node can read and display any information you store in a bot variable**.
+
+ Don't save sensitive information like API keys or passwords in bot variables—use [**configuration variables**](/studio/concepts/variables/scopes/configuration) instead.
+
+
+
+
+ Need help getting started with variables? Check out our [introduction to
+ variables](/studio/concepts/variables/overview).
+
+
+## Read a bot variable
+
+You can use `{{bot.variablename}}` or `@bot.variablename` to read a bot variable. For example, in a **Text** Card:
+
+

diff --git a/src/content/docs/studio/concepts/variables/scopes/configuration.mdx b/src/content/docs/studio/concepts/variables/scopes/configuration.mdx
new file mode 100644
index 0000000..ac2627a
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/scopes/configuration.mdx
@@ -0,0 +1,45 @@
+---
+title: Configuration variables
+---
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+Configuration variables let you **securely store information throughout your bot**.
+
+Like [bot variables](/studio/concepts/variables/scopes/bot), configuration variables are accessible across all Workflows and conversations. The key difference is that configuration variables are **encrypted**. This means an Autonomous Node can't read or display information you store in a configuration variable.
+
+This extra layer of security makes configuration variables great for storing sensitive information, like:
+
+- API Tokens
+- Private IP Addresses
+- Usernames and passwords
+
+
+ If you need your variable to be available globally but don't need/want to store it securely, use a [bot
+ variable](/studio/concepts/variables/scopes/bot).
+
+
+
+ Need help getting started with variables? Check out our [introduction to
+ variables](/studio/concepts/variables/overview).
+
+
+## Create a configuration variable
+
+To create a configuration variable:
+
+1. In the Studio, select **Bot Settings** from the bottom-left corner.
+2. Scroll to the **Configuration Variables** section:
+
+

+
+3. Select **+**, then enter a **Name** and **Value** for your variable:
+
+

+
+## Read a configuration variable
+
+You can use `env.variablename` to read a configuration variable. For example, in an [Execute Code](/studio/concepts/cards/execute-code) Card:
+
+

diff --git a/src/content/docs/studio/concepts/variables/scopes/conversation.mdx b/src/content/docs/studio/concepts/variables/scopes/conversation.mdx
new file mode 100644
index 0000000..e94a52b
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/scopes/conversation.mdx
@@ -0,0 +1,31 @@
+---
+title: Conversation variables
+---
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+Conversation variables let you store and reuse information within the scope of **a single conversation**.
+
+This makes them great for storing information that's only relevant to the current conversation, but that you need to access in multiple Workflows. For example:
+
+- Items in a virtual shopping cart
+- Conversation-specific preferences
+- A checklist to track the completion of sub-Workflows
+
+
+ Information stored in conversation variables is deleted when the current conversation is over. If you need a variable
+ to persist across multiple conversations, use a different [variable
+ scope](/studio/concepts/variables/overview#variable-scopes).
+
+
+
+ Need help getting started with variables? Check out our [introduction to
+ variables](/studio/concepts/variables/overview).
+
+
+## Read a conversation variable
+
+You can use `{{conversation.variablename}}` or `@conversation.variablename` to read a conversation variable. For example, in a **Text** Card:
+
+

diff --git a/src/content/docs/studio/concepts/variables/scopes/user.mdx b/src/content/docs/studio/concepts/variables/scopes/user.mdx
new file mode 100644
index 0000000..29f8de8
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/scopes/user.mdx
@@ -0,0 +1,30 @@
+---
+title: User variables
+---
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+User variables let you store and reuse information within the scope of **a single user**.
+
+Any information you assign to a user variable will follow the user across multiple conversations with your bot. This makes user variables great for storing user-specific information, like:
+
+- Personal details
+- User preferences
+- Notes from previous conversations
+
+
+ If you don't want your variable to follow the user between conversations, use a different [variable
+ scope](/studio/concepts/variables/overview#variable-scopes).
+
+
+
+ Need help getting started with variables? Check out our [introduction to
+ variables](/studio/concepts/variables/overview).
+
+
+## Read a user variable
+
+You can use `{{user.variablename}}` or `@user.variablename` to read a user variable. For example, in a **Text** Card:
+
+

diff --git a/src/content/docs/studio/concepts/variables/scopes/workflow.mdx b/src/content/docs/studio/concepts/variables/scopes/workflow.mdx
new file mode 100644
index 0000000..1c80b99
--- /dev/null
+++ b/src/content/docs/studio/concepts/variables/scopes/workflow.mdx
@@ -0,0 +1,32 @@
+---
+title: Workflow variables
+---
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+Workflow variables let you store and reuse information within the scope of **a single [Workflow](/studio/concepts/workflows)**. They're great for:
+
+- Storing an AI task's output
+- Saving and reusing user input
+- Organizing data returned from an API call
+
+
+ Workflow variables are only accessible in the Workflow they were created in. If you need a variable to be accessible
+ in multiple Workflows, use a different [variable scope](/studio/concepts/variables/overview#variable-scopes).
+
+
+
+ Need help getting started with variables? Check out our [introduction to
+ variables](/studio/concepts/variables/overview).
+
+
+## Read a Workflow variable
+
+You can use `{{workflow.variablename}}` or `@workflow.variablename` to read a Workflow variable. For example, in a **Text** Card:
+
+
+
+
+
+
diff --git a/src/content/docs/studio/concepts/versions.mdx b/src/content/docs/studio/concepts/versions.mdx
new file mode 100644
index 0000000..a8db4c9
--- /dev/null
+++ b/src/content/docs/studio/concepts/versions.mdx
@@ -0,0 +1,39 @@
+---
+title: Versions
+description: View, compare, and revert to previous versions of your bot.
+icon: History
+---
+
+import { Note } from '@/components/callouts'
+
+Versions in Botpress help you track, manage, and control changes made to your bots.
+
+They provide a detailed log of updates, allowing you to view past versions, compare changes, and revert to previous states if necessary. This feature is essential for collaborative bot development, ensuring transparency, accountability, and easy recovery from unintended changes.
+
+## Accessing Versions
+
+The Versions menu can be found on the left-hand menu by clicking on the icon that looks like a clock.
+
+## Creating a new Version
+
+Versions are created in two ways:
+
+1. By clicking on the '+' in the Versions menu and manually creating a new Version
+2. Automatically, every time you publish your bot
+
+It's a good idea to annotate every saved Version you have and indicate any of the major changes or updates made.
+
+## Reverting to a previous Version
+
+From the Versions menu, you can revert to a previous version by clicking into it and restoring to a previous Version. Note that reverting to a previous version will completely overwrite your current bot, including any unsaved changes you may have made.
+
+Botpress can't restore lost or overwritten bot Versions.
+
+
+Note
+
+Pay-as-you-go users have access to 3 saved Versions.
+
+Team Plan subscribers have access to 15 saved Versions.
+
+
diff --git a/src/content/docs/studio/concepts/workflows.mdx b/src/content/docs/studio/concepts/workflows.mdx
new file mode 100644
index 0000000..ca29f85
--- /dev/null
+++ b/src/content/docs/studio/concepts/workflows.mdx
@@ -0,0 +1,209 @@
+---
+title: Workflows
+icon: Workflow
+---
+
+import { Picture } from 'astro:assets'
+import defaultWorkflowsDarkImg from './assets/default-workflows-dark.png'
+import defaultWorkflowsImg from './assets/default-workflows.png'
+import endWorkflowDarkImg from './assets/end-workflow-dark.png'
+import endWorkflowImg from './assets/end-workflow.png'
+import errorWorkflowDarkImg from './assets/error-workflow-dark.png'
+import errorWorkflowImg from './assets/error-workflow.png'
+import flowLogicDarkImg from './assets/flow-logic-dark.png'
+import flowLogicImg from './assets/flow-logic.png'
+import mainWorkflowDarkImg from './assets/main-workflow-dark.png'
+import mainWorkflowImg from './assets/main-workflow.png'
+import newWorkflowDarkImg from './assets/new-workflow-dark.png'
+import newWorkflowImg from './assets/new-workflow.png'
+import timeoutWorkflowDarkImg from './assets/timeout-workflow-dark.png'
+import timeoutWorkflowImg from './assets/timeout-workflow.png'
+import transitionCardDarkImg from './assets/transition-card-dark.png'
+import transitionCardImg from './assets/transition-card.png'
+import workflowDarkImg from './assets/workflow-dark.png'
+import workflowFoldersDarkImg from './assets/workflow-folders-dark.png'
+import workflowFoldersImg from './assets/workflow-folders.png'
+import workflowImg from './assets/workflow.png'
+import workflowsHubDarkImg from './assets/workflows-hub-dark.png'
+import workflowsHubImg from './assets/workflows-hub.png'
+import workflowsMenuDarkImg from './assets/workflows-menu-dark.png'
+import workflowsMenuImg from './assets/workflows-menu.png'
+
+import { Tip, Note } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+{/* vale Botpress.workflows = NO */}
+
+
Workflows are **sequences of steps that your bot takes**:
+
+
+
+
+
+
+Each Workflow represents a reusable, customizable section of your bot's logic. You can use them to organize your bot's behaviour. For example, you might want to:
+
+- Greet users and offer assistance
+- Validate a user response
+- Collect personal data before checking out
+
+Instead of having the logic for each of these tasks in one big sequence, you can put each one in its own Workflow. Then, just [transition](#transition-to-a-workflow) to whichever Workflow you need.
+
+---
+
+## Overview
+
+Workflows are made up of [Nodes](/studio/concepts/nodes/introduction) that determine their behaviour. You can modify the Nodes within a Workflow by dragging and dropping them.
+
+Every Workflow you create has at least two Nodes:
+
+- An **Entry Node** that executes whenever you transition to the Workflow
+- An **Exit Node** which exits the current Workflow and returns to its parent Workflow
+
+You can put any amount of Nodes in between these two—they'll execute in order when you transition to the Workflow.
+
+
+ You can [pass data between Workflows](/studio/concepts/variables/pass-between-workflows)—check out the
+ [variables](/studio/concepts/variables/overview) section for more information.
+
+
+---
+
+## Built-in Workflows
+
+Every bot comes with a few built-in Workflows to handle specific situations gracefully:
+
+
+
+
+
+
+You can modify the contents of each one to suit your needs. Here's a breakdown of each default Workflow.
+
+### Main
+
+The Main Workflow is the entry point for every conversation with your bot. It executes every time a new conversation begins:
+
+
+
+
+
+
+Unlike custom Workflows, the Main Workflow always contains:
+
+- A [Start Node](/studio/concepts/nodes/introduction#start-node) that starts the conversation
+- An [End Node](/studio/concepts/nodes/introduction#end-node) that ends the conversation
+
+### Error
+
+The Error Workflow executes when there's an unexpected error in one of your other Workflows. You can use it to inform the user that something went wrong:
+
+
+
+
+
+
+Instead of an **Exit** Node, the Error Workflow contains an **End** Node. This ensures that the conversation ends after the error occurs.
+
+### Timeout
+
+The Timeout Workflow executes after a period of prolonged inactivity from the user. You can use it to inform the user that the conversation timed out:
+
+
+
+
+
+
+Instead of an **Exit** Node, the Timeout Workflow contains an **End** Node. This ensures that the conversation ends after the timeout occurs.
+
+
You can set a custom timeout delay in your [Bot Settings](/studio/concepts/bot-settings).
+
+### Conversation End
+
+The Conversation End Workflow executes right before the conversation ends explicitly. You can use it to summarize the conversation before it ends, or offer follow-up actions:
+
+
+
+
+
+
+Instead of an **Exit** Node, the **Conversation End** Workflow contains an **End** Node. This ensures that the conversation ends after the Workflow executes.
+
+
+ The **Conversation End** Workflow only executes before the conversation ends explicitly—that is, when a Workflow transitions to an [End Node](/studio/concepts/nodes/introduction#end-node).
+
+Since Autonomous Nodes don't transition to an End Node when the user ends the conversation, they won't transition to the Conversation End Workflow by default.
+
+
+
+---
+
+## Add a Workflow
+
+To add a new Workflow, navigate to the **Workflows** menu in Studio:
+
+
+
+
+
+
+Then, select **Create Workflow** and enter a name for the new Workflow:
+
+
+
+
+
+
+### From Botpress Hub
+
+You can also browse [Botpress Hub](/integrations/get-started/botpress-hub) for user-uploaded Workflows and add them to your bot. Just filter by Workflow to see all available Workflows:
+
+
+
+
+
+
+To add any Workflow, select it, then select **Install Workflow**.
+
+
+ To edit a Workflow you installed from Botpress Hub, you need to make a copy of it within your bot. After installing,
+ select **Make a copy and Edit**—the Workflow will then open in Studio.
+
+
+---
+
+## Transition to a Workflow
+
+Any Workflows you add are available as a [Card](/studio/concepts/cards/introduction) from the **Flow Logic** section of the Card tray:
+
+
+
+
+
+
+To transition to a new Workflow, just add it to the Node you want to transition from:
+
+
+
+
+
+
+---
+
+## Group Workflows in folders
+
+You can group Workflows into folders to keep them organized:
+
+
+
+
+
+
+Just select **Add Folder** in the Workflows menu to create a new folder. Then, you can drag any Workflows (or sub-folders) you want into the folder.
+
+---
+
+## Share a Workflow
+
+You can share any Workflow you create on [Botpress Hub](/integrations/get-started/botpress-hub) to make it available to other users. Just select **Share Workflow**
in the upper-right corner of the Workflow and fill out the required fields.
diff --git a/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-features.png b/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-features.png
new file mode 100644
index 0000000..a40d374
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-features.png differ
diff --git a/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-tips-tricks.png b/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-tips-tricks.png
new file mode 100644
index 0000000..3227d16
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/additional-information/assets/getting-started-tips-tricks.png differ
diff --git a/src/content/docs/studio/guides/advanced/additional-information/assets/languages.png b/src/content/docs/studio/guides/advanced/additional-information/assets/languages.png
new file mode 100644
index 0000000..d14e3e6
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/additional-information/assets/languages.png differ
diff --git a/src/content/docs/studio/guides/advanced/additional-information/assets/translator-agent.png b/src/content/docs/studio/guides/advanced/additional-information/assets/translator-agent.png
new file mode 100644
index 0000000..cd6fd35
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/additional-information/assets/translator-agent.png differ
diff --git a/src/content/docs/studio/guides/advanced/additional-information/botpress-features.mdx b/src/content/docs/studio/guides/advanced/additional-information/botpress-features.mdx
new file mode 100644
index 0000000..fa467e7
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/additional-information/botpress-features.mdx
@@ -0,0 +1,280 @@
+---
+title: Botpress Features
+---
+
+import { Picture } from 'astro:assets'
+import gettingStartedFeaturesImg from './assets/getting-started-features.png'
+
+
+
+## Overall Product Specifications
+
+
+
+
+ |
+ Feature
+ |
+
+
+ Description
+ |
+
+
+
+
+
+
+ |
+ SDK
+ |
+
+
+ The utility functions that can be used as arguments in user custom code. See the [NPM package](https://www.npmjs.com/package/@botpress/sdk) and [API documentation](/api-reference)
+ |
+
+
+
+ |
+ Security
+ |
+
+
+ - Audit logs for all activities in your workspace
- Encryption at rest and in transit
- Rate limits & various HTTP-server limits
- SSO - [talk to our sales representatives](https://botpress.com/contact-us)
+ |
+
+
+
+ |
+ CI/CD
+ |
+
+
+ One-click publish to production
+ |
+
+
+
+ |
+ Multi-Channel Support
+ |
+
+
+ Instantly deliver your bots on all the major messaging channels
- Botpress Webchat
- Facebook Messenger
- Microsoft Teams
- SMS via Twilio
- WhatsApp
- Line
- Viber
- Instagram
- Coming Soon: Intercom, Webhook, Gmail, Rocket.Chat and more.
+ |
+
+
+
+ |
+ Botpress Webchat
+ |
+
+
+ **Create custom message widgets**- Create your own GUI messages using React
- Customizable with CSS
**Flexibility for users**- Multiple simultaneous conversations with the same bot
- Reset & delete conversation (for privacy purposes)
- File-sharing using Shareable link
- Hosted on AWS S3 or BPFS
+ |
+
+
+
+ |
+ Custom Chatbot Branding
+ |
+
+
+ [Rebrand the Botpress Webchat interface](/webchat/get-started/configure-your-webchat)
+ |
+
+
+
+ |
+ Community Support
+ |
+
+
+ - [Botpress forum & community](https://discord.gg/botpress)
- Intercom live support
+ |
+
+
+
+ |
+ Multilingual Support
+ |
+
+
+ - Supported Languages: you can use Botpress to make bots in 100+ languages. However during the early preview of the new Botpress, only English is supported for natural language understanding.
+ |
+
+
+
+ |
+ Conversational AI Management
+ |
+
+
+ - Managed Natural Language Understanding (NLU) Engine - an industrial-grade native NLU engine, from domain specific natural language to structured data
- **Intent classification** - understand the type of action or out of scope conveyed in the sentences and all its participating parts (for example: book a flight, order dinner, buy a product, etc.)
- **Entity extraction** - locate and classify named entities into predefined categories such as person names, organizations, locations, product SKUs, etc. Regex/pattern entities, List entities, Fuzzy matching, pre-built entities
- **Slot tagging** - tag the words which carry meaning to the sentences (for example: landing city, type of meal, etc.)
- **Language identification** - determining the natural language that a document or part thereof is written in (for example: English, French, etc.)
- **Natural Language Understanding**: any number of languages within the same chatbot; the bot is able to detect the user's language and then answer in kind
- **Spell checking** - check for misspellings and automatically fix the spelling mistakes so that the downstream NLU performs more accurately
+ |
+
+
+
+ |
+ Built-in Content Types
+ |
+
+
+ [Supported content types for each channel](/studio/concepts/cards/send-messages#message-types)
+ |
+
+
+
+ |
+ Visual conversation / dialog management
+ |
+
+
+ Visual developer interface to create and management dialog states and topic
- Low-code drag and drop user interface
- Multiple visual flows and subflows with conditions divided by topics
- Multi-turn and the ability to jump from a topic to another seamlessly
- Topic management - process that enables data elements pertaining to a specific topic to be maintained within conversations (for example: user name, SKU number, etc.)
- Conversational detours - while the visual flows represent the "happy paths" that are desired by the conversation designers, detours are about automatically and gracefully handling exceptions
- Template management - use pre-made templates to get started or find inspiration
- Intelligent slot filling - prompting for missing form fields
- Workflow management - group and reuse flows and subflows to embed and manage domain specific knowledge
- Code autocompletion and user interface shortcuts
+ |
+
+
+
+ |
+ FAQ/Q\&A
+ |
+
+
+ Create, manage, and centrally access the most frequently asked questions the users may have
- Context management
- Rich messages
- Message "alternatives" - the bot doesn’t always say the same thing
+ |
+
+
+
+ |
+ Human in the Loop (HITL)
+ |
+
+
+ Straightforward integrations with leading third party HITL, including Salesforce, Zendesk, ServiceNow, Oracle, Intercom, Genesis, Twilio Flex, Nuance and LiveAgent.
+ |
+
+
+
+ |
+ Analytics & continuous bot training
+ |
+
+
+ Dashboards and tools to capture and improve user engagement and bot accuracy
- Misunderstood - capture everything the bot doesn't understand and use it to improve your bot or expand its capabilities
- Engagement
- Conversations
- Interactions
+ |
+
+
+
+ |
+ Testing, debugging, and logging
+ |
+
+
+ End-to-end conversation emulation & testing NLU testing Debugging tools Logging
+ |
+
+
+
+ |
+ Chatbot privacy
+ |
+
+
+ - Sensitive data / conversation obfuscation
- Variable time-based deletion
- Selective data persistence
+ |
+
+
+
+ |
+ JavaScript IDE
+ |
+
+
+ - Easily integrate with your internal systems and any third parties
- Actions & Hooks - create and edit actions within Botpress (for example: call an API). Features typing and intelligent code completion
- VS Code embedded in Botpress Studio
+ |
+
+
+
+ |
+ Terms and Conditions
+ |
+
+
+ [Terms and Conditions](https://botpress.com/company/terms)
+ |
+
+
+
+
+
+## Enterprise-Specific Features
+
+
+
+ | **Feature** |
+ **Description** |
+
+
+ | Enhanced Enterprise Security for bot users |
+ Identity transmission - securely transmit the user identity to the Webchat from the host web page |
+
+
+ | Role-based access control (RBAC) |
+
+ RBAC - Users can be assigned roles, and permissions can be managed with regards to these roles in terms of giving
+ users read and/or write access to specific features
+ |
+
+
+ | Single-Sign On (SSO) |
+
+ Seamlessly link Botpress to your identity provider, OAuth2 for Google, GitHub, Azure
+
+ Talk to sales for more information
+ |
+
+
+ | Scalability |
+ Botpress has you covered: your bot solution adapts instantaneously as your user base grows |
+
+
+ | Monitoring |
+
+ Directly monitor messages left on your community plan
+
+ Set up alerts for messages and keep an eye on your monthly message traffic
+ |
+
+
+ | Enterprise Support |
+
+ Advanced Botpress technical support
+
+ Standard: EST business hours
+
+ Premium: 24/7
+
+ SLA
+ |
+
+
+ | Integrations |
+
+
+ For a full list of integrations check out our [integration hub](https://botpress.com/hub)
+
+ |
+
+
+
+ | Collaboration |
+
+ Real-time collaboration, with workspaces to organize both bots and developer work
+
+ Realtime collaborative interface (with lock management)
+
+ Workspaces - logical unit that groups up your conversational assistants based on the purpose of the bots or
+ for something more granular such as for a specific task, etc.
+ |
+
+
diff --git a/src/content/docs/studio/guides/advanced/additional-information/languages.mdx b/src/content/docs/studio/guides/advanced/additional-information/languages.mdx
new file mode 100644
index 0000000..15c6536
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/additional-information/languages.mdx
@@ -0,0 +1,789 @@
+---
+title: Languages
+---
+
+import { Picture } from 'astro:assets'
+import languagesImg from './assets/languages.png'
+import translatorAgentImg from './assets/translator-agent.png'
+
+import YouTube from '@/components/YouTube.astro'
+
+
+
+## Supported Languages
+
+With Botpress, you can build bots that are able to converse with people in more than 100+ languages!
+
+
+
+
+ |
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+ |
+ Afrikaans
+ |
+
+
+ Albanian
+ |
+
+
+ Alemannic
+ |
+
+
+ Amharic
+ |
+
+
+ Arabic
+ |
+
+
+
+ |
+ Aragonese
+ |
+
+
+ Armenian
+ |
+
+
+ Assamese
+ |
+
+
+ Asturian
+ |
+
+
+ Azerbaijani
+ |
+
+
+
+ |
+ Bashkir
+ |
+
+
+ Basque
+ |
+
+
+ Bavarian
+ |
+
+
+ Belarusian
+ |
+
+
+ Bengali
+ |
+
+
+
+ |
+ Bihari
+ |
+
+
+ Bishnupriya Manipuri
+ |
+
+
+ Bosnian
+ |
+
+
+ Breton
+ |
+
+
+ Bulgarian
+ |
+
+
+
+ |
+ Burmese
+ |
+
+
+ Catalan
+ |
+
+
+ Cebuano
+ |
+
+
+ Central Bicolano
+ |
+
+
+ Chechen
+ |
+
+
+
+ |
+ Chinese (Simplified and Traditional)
+ |
+
+
+ Chuvash
+ |
+
+
+ Corsican
+ |
+
+
+ Croatian
+ |
+
+
+ Czech
+ |
+
+
+
+ |
+ Danish
+ |
+
+
+ Divehi
+ |
+
+
+ Dutch
+ |
+
+
+ Eastern Punjabi
+ |
+
+
+ Egyptian Arabic
+ |
+
+
+
+ |
+ Emilian-Romagnol
+ |
+
+
+ Erzya
+ |
+
+
+ Esperanto
+ |
+
+
+ Estonian
+ |
+
+
+ Fiji Hindi
+ |
+
+
+
+ |
+ Finnish
+ |
+
+
+ French
+ |
+
+
+ Galician
+ |
+
+
+ Georgian
+ |
+
+
+ German
+ |
+
+
+
+ |
+ Goan Konkani
+ |
+
+
+ Greek
+ |
+
+
+ Gujarati
+ |
+
+
+ Haitian
+ |
+
+
+ Hebrew
+ |
+
+
+
+ |
+ Hill Mari
+ |
+
+
+ Hindi
+ |
+
+
+ Hungarian
+ |
+
+
+ Icelandic
+ |
+
+
+ Ido
+ |
+
+
+
+ |
+ Ilokano
+ |
+
+
+ Indonesian
+ |
+
+
+ Interlingua
+ |
+
+
+ Irish
+ |
+
+
+ Italian
+ |
+
+
+
+ |
+ Japanese
+ |
+
+
+ Javanese
+ |
+
+
+ Kannada
+ |
+
+
+ Kapampangan
+ |
+
+
+ Kazakh
+ |
+
+
+
+ |
+ Khmer
+ |
+
+
+ Kirghiz
+ |
+
+
+ Korean
+ |
+
+
+ Kurdish (Kurmanji)
+ |
+
+
+ Kurdish (Sorani)
+ |
+
+
+
+ |
+ Latin
+ |
+
+
+ Latvian
+ |
+
+
+ Limburgish
+ |
+
+
+ Lithuanian
+ |
+
+
+ Lombard
+ |
+
+
+
+ |
+ Low Saxon
+ |
+
+
+ Luxembourgish
+ |
+
+
+ Macedonian
+ |
+
+
+ Maithili
+ |
+
+
+ Malagasy
+ |
+
+
+
+ |
+ Malay
+ |
+
+
+ Malayalam
+ |
+
+
+ Maltese
+ |
+
+
+ Manx
+ |
+
+
+ Marathi
+ |
+
+
+
+ |
+ Mazandarani
+ |
+
+
+ Meadow Mari
+ |
+
+
+ Minangkabau
+ |
+
+
+ Mingrelian
+ |
+
+
+ Mongolian
+ |
+
+
+
+ |
+ Mangolian
+ |
+
+
+ Nahautl
+ |
+
+
+ Neapolitan
+ |
+
+
+ Nepali
+ |
+
+
+ Newar
+ |
+
+
+
+ |
+ North Frisian
+ |
+
+
+ Northern Sotho
+ |
+
+
+ Norwegian (Bokmål)
+ |
+
+
+ Norwegian (Nynorsk)
+ |
+
+
+ Occitan
+ |
+
+
+
+ |
+ Oriya
+ |
+
+
+ Ossetian
+ |
+
+
+ Palatinate German
+ |
+
+
+ Pashto
+ |
+
+
+ Persian
+ |
+
+
+
+ |
+ Piedmontese
+ |
+
+
+ Polish
+ |
+
+
+ Portuguese
+ |
+
+
+ Quechua
+ |
+
+
+ Romanian
+ |
+
+
+
+ |
+ Romansh
+ |
+
+
+ Russian
+ |
+
+
+ Sakha
+ |
+
+
+ Sanskrit
+ |
+
+
+ Sardinian
+ |
+
+
+
+ |
+ Scots
+ |
+
+
+ Scottish Gaelic
+ |
+
+
+ Serbian
+ |
+
+
+ Serbo-Croatian
+ |
+
+
+ Sicilian
+ |
+
+
+
+ |
+ Sindhi
+ |
+
+
+ Sinhalese
+ |
+
+
+ Slovak
+ |
+
+
+ Slovenian
+ |
+
+
+ Somali
+ |
+
+
+
+ |
+ Southern Azerbaijani
+ |
+
+
+ Spanish
+ |
+
+
+ Sundanese
+ |
+
+
+ Swahili
+ |
+
+
+ Swedish
+ |
+
+
+
+ |
+ Tagalog
+ |
+
+
+ Tajik
+ |
+
+
+ Tamil
+ |
+
+
+ Tatar
+ |
+
+
+ Telugu
+ |
+
+
+
+ |
+ Thai
+ |
+
+
+ Tibetan
+ |
+
+
+ Turkish
+ |
+
+
+ Turkmen
+ |
+
+
+ Ukrainian
+ |
+
+
+
+ |
+ Upper Sorbian
+ |
+
+
+ Urdu
+ |
+
+
+ Uyghur
+ |
+
+
+ Uzbek
+ |
+
+
+ Venetian
+ |
+
+
+
+ |
+ Vietnamese
+ |
+
+
+ Volapük
+ |
+
+
+ Walloon
+ |
+
+
+ Waray
+ |
+
+
+ Welsh
+ |
+
+
+
+ |
+ West Flemish
+ |
+
+
+ West Frisian
+ |
+
+
+ Western Punjabi
+ |
+
+
+ Yiddish
+ |
+
+
+ Yoruba
+ |
+
+
+
+ |
+ Zazaki
+ |
+
+
+ Zeelandic
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+## Translator Agent
+
+
+
+
+
+The Translator Agent allows your bot to interact with users in different languages, breaking language barriers and expanding the range of your bot's audience.
+
+### Configuration
+
+- **Automatically Detect User Language** - When enabled, the Translator Agent will automatically detect the user's language from their input.
+
+Activating this feature consequently sets the `{{user.TranslatorAgent.language}}` variable when it's not already defined.
+
+### Exposed Variables
+
+- **user.TranslatorAgent.language**: This variable represents the detected language of the user.
+
+### Example - setting language to french
+
+1. Open the Toolbox Cards and drag the **Set User Language** Card into your first node(ideally).
+2. Specify a language. In this case, we will use `fr` for French.
+
+The Translator Agent automatically translates the bot's responses into the user's language once activated. If you wish to define the user's language manually, you can directly set the `{{user.TranslatorAgent.language}}` variable.
+
+This variable is set to `null` by default, which means that the Translator Agent will automatically detect the user's language from their input.
+
+### Resetting the language
+
+Drag the **Reset User Language** Card into your Workflow. This will reset the `{{user.TranslatorAgent.language}}` variable to `null`.
+
+You can do this in Execute Code card as well:
+
+```javascript
+//use null to reset the language; otherwise, set it to a language code
+{{user.TranslatorAgent.language}} = null;
+```
diff --git a/src/content/docs/studio/guides/advanced/additional-information/limits-and-quotas-of-botpress-cloud.mdx b/src/content/docs/studio/guides/advanced/additional-information/limits-and-quotas-of-botpress-cloud.mdx
new file mode 100644
index 0000000..c5a7046
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/additional-information/limits-and-quotas-of-botpress-cloud.mdx
@@ -0,0 +1,52 @@
+---
+title: Platform Limits
+---
+
+## Limits and Quotas of Botpress Cloud
+
+Botpress sets certain limits and quotas to ensure the stability of the platform and the bots created by customers and the community.
+
+### Limits
+
+| **Limit** | **Amount** | **Technical Name** |
+| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------------- |
+| The maximum size for the bot settings | 20KB | Bot Configuration |
+| The maximum number of integrations that can be installed in a bot | 30 | Bot Installed Integrations |
+| The maximum size for integration settings | 20KB | Bot Integration Configuration |
+| The maximum number of [Schedule Triggers](/studio/concepts/cards/fixed-schedule) per bot | 40 | Bot Recurring Events |
+| The maximum size for the Schedule Trigger event payload | 128KB | Bot Recurring Event Payload Size |
+| The maximum number of events (used as Triggers) that an integration can define in its definition file | 20 | Event Definition |
+| The maximum number of channels an integration can support (e.g., direct messages, public channels, threads) | 10 | Integration Channels |
+| The maximum number of message types that an integration channel can support | 20 | Integration Channel Message Types |
+| The maximum number of unique OAuth identifiers an integration can have | 50 | Integration OAuth Identifier |
+| The maximum number of versions a custom integration can have | 50 | Integration Versions |
+| The maximum size for the payload of messages | 128KB | Message Payload Size |
+| The maximum size for the integration | 20KB | Schema Size schemas |
+| The maximum number of free-form object variables a bot or an integration can have (limited by the Conversation State Size of 128KB) | 5 | State Definitions |
+| The maximum size for the conversation state serialized as JSON | 128KB | Conversation State Size |
+| The maximum number of tag definitions per bot | 50 | Tag Definitions |
+| The maximum number of columns per table | 20 | Table columns |
+| End-user message / event max throughput | 600 requests / minute / bot | API limit |
+| Maximum size of deployed bot (excluding file storage) | 100MB | Bot Size |
+
+### Quotas
+
+Quotas are limits that can be increased depending on the plan you're subscribed to. For more information, please check our [detailed pricing page](https://botpress.com/pricing).
+
+| **Quota** | **Amount** | **Technical Name** |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ---------------------- |
+| The maximum time for a bot to process a message or an event before timing out (not the same as [Inactivity Timeout](/studio/concepts/bot-settings#inactivity-timeout)) | 60s | Invocation Timeout |
+| The maximum combined size of documents uploaded to be sent as media messages (e.g., Images, Audios, Videos, Files, and Cards) | 100MB | Storage Size |
+| The maximum number of bots per workspace | 5 | Amount of Bots |
+| The maximum number of members that can be added to a workspace (Collaborators can have roles such as Viewer, Billing Manager, Developer, Manager, Administrator) | 3 | Amount of Members |
+| The maximum number of vectors (content chunks) in a Knowledge Base per bot (roughly equivalent to 100MB of documents) | 5,000 | Knowledge Base Vectors |
+| The maximum number of records/items that can be stored in a table per bot | 5,000 | Table Rows |
+| The maximum number of times a bot can be invoked per month (An invocation occurs when a new conversation is created, when a conversation resumes after a timeout, and when a Trigger is executed) | 25,000 | Invocation Calls |
+| The maximum number of times a bot can call cognitive (AI) services per month | 4,000 | Cognitive Calls |
+| The maximum number of bot invocations per minute | 100 | Bot Rate Limit |
+| The maximum number of custom integrations that can be created per workspace | 20 | Owned Integrations |
+| The maximum number of AI model credits that can be used per month | 5,000 | LLM Model Credits |
+| The maximum number of row sizes in a table. However, you can increase it from the factors section from the API ([Read More Here](/studio/concepts/tables#create-table)) | 4kb | Table Row Size |
+| The maximum number of HTTP requests sent from the emulator | 30 requests / minute / bot | External calls |
+| Botpress API limit [https://api.botpress.cloud/](https://api.botpress.cloud/)\* | 100 requests / second | API limit |
+| Integrations API limit [https://webhook.botpress.cloud/](https://webhook.botpress.cloud/)\* | 100 requests / second / bot | API limit |
diff --git a/src/content/docs/studio/guides/advanced/additional-information/tips-tricks.mdx b/src/content/docs/studio/guides/advanced/additional-information/tips-tricks.mdx
new file mode 100644
index 0000000..560267d
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/additional-information/tips-tricks.mdx
@@ -0,0 +1,165 @@
+---
+title: Tips & Tricks
+---
+
+import { Picture } from 'astro:assets'
+import gettingStartedTipsTricksImg from './assets/getting-started-tips-tricks.png'
+
+import { Note, Info } from '@/components/callouts'
+
+
+
+## Using Markdown in Botpress
+
+Markdown is a lightweight markup language that you can use to add formatting elements to plain text documents. It's a simple way to add formatting to your text. You can use Markdown in Botpress to format your text in the following ways:
+
+| Markdown Syntax | Example |
+| --------------- | ------------------------------------------------------------------------------ |
+| Bold | `**Bold**` |
+| Italic | `*Italic*` |
+| Strikethrough | `~~Strikethrough~~` |
+| Code | `Code` |
+| Code Block | `Code Block` |
+| Link | `[botpress.com](https://www.botpress.com)` |
+| Image | `` |
+| Unordered List | `- Item 1` |
+| Ordered List | `1. Item 1` |
+| Horizontal line | `---` |
+
+
+Info
+
+Markdown is supported only in Webchat Integration
+
+
+
+## Timely Greeting
+
+Pick an Execute Code card and enter the prompt as "Timely Greeting". It will generate the following code:
+
+```javascript
+const currentTime = luxon.DateTime.now()
+const currentHour = currentTime.hour
+
+let timelyGreeting = ''
+if (currentHour >= 0 && currentHour < 12) {
+ timelyGreeting = 'Good morning'
+} else if (currentHour >= 12 && currentHour < 18) {
+ timelyGreeting = 'Good afternoon'
+} else {
+ timelyGreeting = 'Good evening'
+}
+
+workflow.timelyGreeting = timelyGreeting
+```
+
+This code will set the variable `timelyGreeting` to the appropriate greeting based on the current time. Make sure to create this variable in your Workflow.
+
+## Using External APIs in Botpress
+
+These are guides on using the Execute Code Card in Botpress to access external APIs to read and update data.
+
+The API calls will be performed using the Botpress built-in Axios client, and the code will run in the Execute Code Card.
+
+### Example - [The Bored API](https://www.boredapi.com/)
+
+The Bored API's motto is : Let's find you something to do! We will be using Bored API as an example of how to call APIs to fetch information.
+
+1. (Optional) Create a Workflow variable to store the information retrieved from the API. In this example, we will create a variable named `participantType`.
+2. Pick the **Execute Code** Card and disable the Generative AI by clicking on the ✨ button.
+3. Paste the following code in the Execute Code Card:
+
+```typescript
+const response = await axios.get('https://www.boredapi.com/api/activity?participants=1')
+workflow.participantType = response.data.activity
+```
+
+Response:
+
+```typescript
+ {
+ "activity": "Go stargazing",
+ "type": "relaxation",
+ "participants": 1,
+ "price": 0,
+ "link": "",
+ "key": "8832605",
+ "accessibility": 0.1
+ }
+```
+
+### Send Emails using [SendGrid API](https://sendgrid.com/)
+
+You can choose any other provider, like Gmail, Microsoft, etc. But you will need to change the code based on the provider you want to integrate with.
+
+1. **Create a free SendGrid[account](https://sendgrid.com/pricing/ 'account')**: For trial purposes.
+2. **Navigate to Email API**: After logging into your new account, click on **Email API** in the menu, then select **Integration Guide**.
+3. **Create an Identity**: Provide your details when prompted and click **Create**. Verify your identity through the verification email you receive.
+4. **Create an[API Key](https://app.sendgrid.com/settings/api_keys 'API Key')**: Click on **Create API Key** at the top right corner and name the key for your reference.
+5. **Save the API Key**: After creating the key, copy the key value for later use. Remember to keep it safe.
+6. **Configure Botpress**: Open your bot in Botpress, and add an **Execute Code** card. Ensure to disable the generative AI within the card.
+7. **Paste the Code**: Adjust the following variables in the code and paste it into the card:
+ - `sendgrid_api_key`: This is the API key generated in the SendGrid [API Key](https://app.sendgrid.com/settings/api_keys 'API Key').
+ - `from_email`: This is the email you configured as the sender.
+ - `to_email`: This is the email to which you are sending.
+
+```typescript
+const sendgrid_api_key = *********
+const from_email = '**************'
+const to_email = '*****************'
+
+const response = await axios.post(
+ 'https://api.sendgrid.com/v3/mail/send',
+ {
+ personalizations: [{to: [{email: to_email}]}],
+ from: {
+ email: from_email
+ },
+ subject: 'Sending with SendGrid is Fun',
+ content: [
+ {
+ type: 'text/plain',
+ value: 'and easy to do anywhere, even with cURL'
+ }
+ ]
+ },
+ {
+ headers: {
+ Authorization: 'Bearer ' + SENDGRID_API_KEY,
+ 'Content-Type': 'application/json'
+ }
+ }
+)
+```
+
+After successfully integrating the SendGrid API into Botpress, it's time to test it.\
+For more information: [https://docs.sendgrid.com/for-developers/sending-email/api-getting-started](https://docs.sendgrid.com/for-developers/sending-email/api-getting-started)
+
+### Use ChatGPT API in Execute Code
+
+If you are using Botpress and want to integrate the ChatGPT API to generate AI-powered responses for your bot, follow these simple steps:
+
+Step 1: Create a variable in your Botpress Workflow to store the ChatGPT API's response.
+
+Step 2: Add the **Execute Code** card to your Botpress Workflow and paste the code below:
+
+```typescript
+const apiKey = '
';
+const {data} = await axios.post("https://api.openai.com/v1/chat/completions", {
+ "model": "gpt-3.5-turbo-0301",
+ "messages": [{"role": "user", "content": event.preview}]
+}, { headers: {'Authorization': `Bearer ${apiKey}`}});
+
+workflow.variableName = data.choices[0].message.content;
+```
+
+Make sure to replace **``** with your actual OpenAI API key, and `variableName` with the name of the variable you created in Step 1.
+
+Step 3: Test your bot in the Botpress Emulator to see if it's generating AI-powered responses.
+
+
+Note
+
+It's important to note that using this method, ChatGPT doesn't preserve the context of the messages that you've sent. However, it's a great way to get started with integrating AI-powered responses into your bot without needing any technical knowledge.
+
+
diff --git a/src/content/docs/studio/guides/advanced/assets/download-start-github.png b/src/content/docs/studio/guides/advanced/assets/download-start-github.png
new file mode 100644
index 0000000..343a7bc
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/assets/download-start-github.png differ
diff --git a/src/content/docs/studio/guides/advanced/assets/import-bot.png b/src/content/docs/studio/guides/advanced/assets/import-bot.png
new file mode 100644
index 0000000..7d6905b
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/assets/import-bot.png differ
diff --git a/src/content/docs/studio/guides/advanced/assets/improper-workflow-exit.png b/src/content/docs/studio/guides/advanced/assets/improper-workflow-exit.png
new file mode 100644
index 0000000..160a07b
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/assets/improper-workflow-exit.png differ
diff --git a/src/content/docs/studio/guides/advanced/assets/workflow-example.png b/src/content/docs/studio/guides/advanced/assets/workflow-example.png
new file mode 100644
index 0000000..82a3e01
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/assets/workflow-example.png differ
diff --git a/src/content/docs/studio/guides/advanced/best-practices-for-state-management.mdx b/src/content/docs/studio/guides/advanced/best-practices-for-state-management.mdx
new file mode 100644
index 0000000..9cea3bd
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/best-practices-for-state-management.mdx
@@ -0,0 +1,128 @@
+---
+title: State Management
+description: >-
+ Manage the 128 KB state size limit in Botpress by optimizing Workflows,
+ clearing unused variables, and minimizing large data usage.
+---
+
+import { Picture } from 'astro:assets'
+import improperWorkflowExitImg from './assets/improper-workflow-exit.png'
+import workflowExampleImg from './assets/workflow-example.png'
+
+## Overview
+
+Efficient state management is crucial for optimizing bot performance in Botpress. This guide outlines best practices to avoid performance degradation and errors caused by exceeding the **128 KB state size limit**, ensuring your bot operates seamlessly.
+
+---
+
+## Understanding State Size Limits
+
+Botpress enforces a **state size limit of 128 KB** to maintain optimal performance. Poorly managed state variables, especially in nested Workflows, can lead to:
+
+- **State bloat**: Accumulation of unnecessary or oversized variables.
+
+- **Performance issues**: Slower bot responses as state size grows.
+
+- **Errors**: Logs showing state size limit exceeded.
+
+---
+
+## Avoiding Common Workflow Design Pitfalls
+
+### Workflow Structure and State Retention
+
+How Workflows are designed impacts the state management. Consider two scenarios:
+
+### Scenario 1: Proper Workflow Exit
+
+- **Workflow 1** ends completely before transitioning to **Workflow 2**.
+
+- Variables from Workflow 1 are cleared upon exit, keeping the state clean.
+
+**Example:**
+
+Workflow 1 → **End** → Workflow 2 → **End**
+
+
+
+### Scenario 2: Improper Workflow Exit
+
+- **Workflow 1** transitions directly into **Workflow 2** without exiting.
+
+- Variables from Workflow 1 persist until **Workflow 3** finishes, causing state size to increase unnecessarily.
+
+**Example:**
+
+Workflow 1 → Workflow 2 → Workflow 3 → **End**
+
+
+
+---
+
+## Best Practices for State Management
+
+### 1. Design Workflows with Proper Exits
+
+Ensure that each Workflow completes before initiating the next. This prevents unused variables from lingering in the state.
+
+**Best Practice Workflow Design:**
+
+Workflow 1 → End
+
+Workflow 2 → End
+
+### 2. Manually Clear Unused Variables
+
+In scenarios where restructuring Workflows is impractical, manually clear state variables to manage size effectively.
+
+**Implementation Tips:**
+
+- Remove variables that are no longer needed by setting it to null value or by reusing it.
+
+### 3. Minimize Use of Large Variables in Main Workflow
+
+Avoid storing large data structures (e.g., arrays, objects) in the main Workflow (`wf-main`). Instead, limit variables to essentials for transitions or core logic.
+
+**Best Practices:**
+
+- Move non-essential or large variables to sub-Workflows.
+
+- Use modular Workflows for better management.
+
+### 4. Monitor and Audit State Size
+
+Regularly inspect and optimize state size to identify potential issues early.
+
+**Tools and Techniques:**
+
+- Use Botpress debugging tools to examine `variable_values`.
+
+- Audit Workflow designs periodically to ensure compliance with best practices.
+
+---
+
+## Optimizing Nested Workflow Designs
+
+Nested Workflows can be efficient but require careful handling to avoid state retention issues. Follow these strategies:
+
+1. **Plan Transitions Carefully**: Design clear entry and exit points for each Workflow.
+
+2. **Use Modular Sub-Workflows**: Break Workflows into smaller, task-specific components.
+
+3. **Limit Parent Variable Retention**: Clear parent Workflow variables when transitioning to nested Workflows.
+
+---
+
+## Conclusion
+
+Adhering to these state management best practices ensures your bot performs optimally, avoids the **128 KB state size limit**, and maintains clean and efficient Workflows:
+
+1. Design Workflows with proper exits.
+
+2. Manually clear unused variables when needed.
+
+3. Minimize use of large variables in the main Workflow.
+
+4. Regularly monitor and audit state size.
+
+By implementing these guidelines, you’ll enhance bot performance, reduce errors, and provide a better user experience.
diff --git a/src/content/docs/studio/guides/advanced/event-properties.mdx b/src/content/docs/studio/guides/advanced/event-properties.mdx
new file mode 100644
index 0000000..b387a4d
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/event-properties.mdx
@@ -0,0 +1,24 @@
+---
+title: Event Properties
+---
+
+import Tooltip from '@/components/Tooltip.astro'
+import IncomingEvent from '@/components/IncomingEvent.astro'
+import { Warning } from '@/components/callouts'
+
+Whenever an event occurs during your bot's execution—like a message being sent—you can access details about that event using the `event` object's properties.
+
+The `event` object is available [wherever you can use code in Botpress Studio](/studio/guides/advanced/use-code). This includes:
+
+- [Hooks](/studio/concepts/hooks)
+- [Actions](/studio/concepts/actions)
+- [Execute Code Cards](/studio/concepts/cards/execute-code)
+
+You can also access the `event` object within certain [Cards](/studio/concepts/cards/introduction)' configuration fields.
+
+
+ This documentation omits certain properties of the `event` object which exist to maintain internal functionality and
+ aren't useful for bot builders.
+
+
+
diff --git a/src/content/docs/studio/guides/advanced/execute-code.mdx b/src/content/docs/studio/guides/advanced/execute-code.mdx
new file mode 100644
index 0000000..57d29b9
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/execute-code.mdx
@@ -0,0 +1,120 @@
+---
+title: Execute Code
+excerpt: ''
+deprecated: false
+hidden: true
+metadata:
+ title: ''
+ description: ''
+ robots: index
+next:
+ description: ''
+---
+
+The Execute Code card allows you to run custom code (in JavaScript) in the context of the current Workflow. This code can also be generated automatically using AI. This is useful for making API calls, performing calculations, or any other custom logic you may need.
+
+> 👍 Generative AI
+>
+> Using this natural language feature you can instruct AI to generate the different pieces of code your bot needs to run, and it's contextual, considers your variables and your conversation's context.
+
+
+
+## Inbuilt Packages
+
+The below packages are already imported and available for use in the Execute Code card.
+
+- [Axios](https://axios-http.com/docs/api_intro)
+- [Lodash](https://lodash.com/docs/4.17.15)
+- [Moment Luxon](https://moment.github.io/luxon/#/?id=luxon)
+
+
+
+## How to Use
+
+1. Drag and drop the Execute Code card into a Node or click on the **+ Add Card** button in the Node and select Execute Code.
+2. Write what you want to do in the input field.
+
+For example, if you want to make an API call, you can write the following:
+
+```
+ Make an API Call to weatherAPI and store the result in a Workflow variable
+```
+
+3. Check if the Code satisfies your needs and **Accept** or **Undo** the changes.
+4. This will automatically generate the description of the code in the Code Card.
+
+
+
+## Versioning
+
+Versioning allows you to go back and forth between different versions of the code. This is useful if you want to try out different versions of the code and see which one works best.
+
+1. Once you **Accept**, you can rewrite the code and **Accept** again. This will create a new version of the code.
+2. You can check the changes between versions, and once you're satisfied with the code, you can **Accept** it or **Undo** it.
+3. Use the arrows to go back and forth between versions.
+
+
+
+## Examples
+
+Input: **I want to find the difference between the variables `startDate` and the `endDate`**
+
+Generated Output:
+
+```typescript
+const startDate = luxon.fromISO(workflow.startDate) // convert the startDate string to a luxon DateTime object
+const endDate = luxon.fromISO(workflow.endDate) // convert the endDate string to a luxon DateTime object
+const diffInDays = endDate.diff(startDate, 'days').toObject().days // find the difference between the two dates in days
+// store the difference in days in the Workflow variable 'dateDiff' as requested
+workflow.dateDiff = diffInDays
+```
+
+---
+
+Input: **I want to get all my issues from Jira filtered by what isn't done**
+
+Generated Output:
+
+```typescript
+const jiraUrl = 'https://your-jira-url.com'
+const jiraUsername = 'your-jira-username'
+const jiraPassword = 'your-jira-password'
+
+// get the current date and time in ISO format
+const now = luxon.local().toISO()
+
+// create the JQL query to get all issues that aren't done
+const jql = `status != Done AND updated >= "${now}" ORDER BY updated DESC`
+
+// set the request headers for Jira API
+const headers = {
+ 'Content-Type': 'application/json',
+ Authorization: `Basic ${btoa(`${jiraUsername}:${jiraPassword}`)}`,
+}
+
+// make the request to Jira API to get all issues that aren't done
+const response = await axios.get(`${jiraUrl}/rest/api/2/search?jql=${jql}`, { headers })
+
+// filter the response to only keep the issues that aren't done
+const issues = _.filter(response.data.issues, (issue) => issue.fields.status.name !== 'Done')
+```
+
+
+
+## Transitioning from Another Language to Botpress
+
+If you're transitioning from another programming language to Botpress, we've got you covered. With the power of ChatGPT, converting simple code snippets, such as making API requests, is now easier than ever.
+
+Step 1: Take your existing code from another programming language. This could be in a language like Python, C#, or any other language you're coming from.
+
+Step 2: Paste the code snippet you have into ChatGPT and add this instruction below it.
+
+```text
+Convert the code above to deno. Save the variable results to the Workflow object (global object available in the code block). Use axios for http requests and use it directly without the "async" keyword. For date management use the luxon library. For string manipulation use the lodash library. All of these libraries are already imported.
+```
+
+Step 3: Paste the result of ChatGPT into the Execute Code card.
+
+Step 4: Test your code and make sure it works as expected.
+
+Step 5: If you need to make any changes, you can do so by editing the code directly or by adding new instructions in the top input of the Execute Code card.
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/analyze-llmz-responses.mdx b/src/content/docs/studio/guides/advanced/exporting-data/analyze-llmz-responses.mdx
new file mode 100644
index 0000000..1d74051
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/analyze-llmz-responses.mdx
@@ -0,0 +1,132 @@
+---
+title: Accessing The Autonomous Nodes Thought Process
+description: >-
+ Analyze Knowledge Base responses from Autonomous Nodes in Botpress with the
+ “After LLMz Execution” hook.
+
+
+ Capture metrics like query content, response source, and user context for
+ precise insights into Knowledge Base interactions and improved bot
+ performance.
+---
+
+import { Note } from '@/components/callouts'
+
+
+Note
+
+If you are looking to simply understand a response in the emulator, you can use the inspect button to get information about the Autonomous nodes thinking. But for other use cases, Botpress allows you to create a JavaScript hook that allows you do something with the data programmatically.
+
+
+
+## Using LLMz hooks
+
+Sometimes you want to do something with that information in your production bots, perhaps for analytics, perhaps for figuring out issues. LLMz hooks allow you to do that. You can use them to monitor and analyze responses from LLMz-powered Autonomous Nodes, especially when they retrieve information from the Knowledge Base (KB), and you can send the information to a Botpress Table, or to your preferred analytics tool.
+
+You can follow the [Botpress guide](/studio/guides/advanced/exporting-data/streaming-analytics-from-within-your-bot-with-hooks) for setting up streaming analytics for messages, but if you'd like to get information on LLMz logic, you can follow these steps to adjust for this.
+
+### Step 1: Setting Up Your Analytics Tool
+
+Start by configuring your analytics tool to capture data from your Botpress bot. Refer to your tool’s documentation to obtain any necessary API keys or project identifiers.
+
+Likewise, if you'd like to use Botpress Analytics, or Botpress Tables, you can also do so.
+
+### Step 2: Configuring the "After LLMz Execution" Hook
+
+The **After LLMz Execution** hook can be set up to collect data whenever an Autonomous Node retrieves and responds with information from the Knowledge Base. This hook is triggered each time the node generates a response, enabling you to capture KB interactions.
+
+To set up this hook:
+
+1. Navigate to the **Hooks** tab in **Botpress Studio**.
+2. Click **Create Hook** and select the **After LLMz Execution** hook.
+
+This hook function provides access to two key parameters:
+
+- `event`: The [Event object](/studio/guides/advanced/event-properties) with details about the interaction.
+- `execution`: An object containing data on the LLMz execution, including details of each iteration and response content. More information on the `execution` object structure is provided [below](#the-execution-object).
+
+## Example Code for the After LLMz Execution Hook
+
+The code below demonstrates how to capture analytics data when an Autonomous Node references information from the Knowledge Base.
+
+```javascript
+// Only execute if Knowledge Base requests were made
+if (event?.kb?.results?.length) {
+ const botAnalyticsData = {
+ // Timestamp of the event
+ time: event.createdOn.getTime(),
+ // Unique identifiers
+ $insert_id: event.id, // Prevents duplicate events
+ distinct_id: event.userId, // Identifies unique users
+ bot_id: event.botId,
+ conversation_id: event.conversationId,
+ // Knowledge Base interaction data
+ query: event.preview, // User's query to the Knowledge Base
+ result: event?.kb?.results[0].content, // Matching KB content fragment
+ fileName: event?.kb?.results[0].title, // Source document name
+
+ // Bot response data - formatted message sent to user
+ autonomousNodeResponse: execution.iterations[execution.iterations.length - 1].message,
+
+ // Context information
+ current_flow: event.state.context.currentFlow,
+ current_node: event.state.context.currentNode,
+ current_card: event.state.context.currentCard,
+ }
+
+ // Replace with your analytics tool's API endpoint
+ const projectToken = ''
+ await axios.post(
+ '',
+ [
+ {
+ event: 'Outbound Message',
+ properties: botAnalyticsData,
+ },
+ ],
+ {
+ headers: {
+ Authorization: `Basic ${btoa(projectToken + ':')}`,
+ },
+ }
+ )
+}
+```
+
+### The `execution` Object
+
+The `execution` object provides detailed information about the actions taken by the Autonomous Node, specifically capturing each iteration and its outcome. This includes messages sent, code executed, signals received, and more. Here’s an in-depth look at its structure and contents:
+
+### Structure of `execution` Object
+
+- `status`: String indicating the overall status of the execution, e.g., `"success"`, `"partial"`, `"failure"`.
+
+- `iterations`: Array of objects, each representing a step or interaction in the Autonomous Node’s execution. Each iteration contains:
+ - `message`: The text response generated at this stage.
+ - `code`: Code executed during this iteration, often in response to specific queries.
+ - `variables`: Object holding variables used within the iteration.
+ - `status`: Status of the individual iteration, e.g., `"partial"`, `"success"`.
+ - `signal`: Information on any signals received, often in the form of structured `ThinkSignal` or other signals, detailing contextual reasoning.
+ - `started_ts`: Timestamp (in milliseconds) indicating when the iteration started.
+ - `ended_ts`: Timestamp (in milliseconds) when the iteration concluded.
+ - `llm`: Object detailing the large language model used, including its version and parameters.
+ - `mutations`: Array of any mutations or transformations applied to variables.
+ - `traces`: Trace data related to the LLM's decisions and actions.
+ - `messages`: Messages used or processed within this step.
+ - `notebook`: Object representing any generated or stored notebook content for reference.
+
+- `context`: Contains settings, variables, and tools relevant to the execution:
+ - `__options`: Execution settings such as the model version, number of loops, temperature, and specific instructions.
+ - `transcript`: Transcript of messages exchanged, with each entry detailing user and bot interactions.
+ - `getMessages`: Function for retrieving messages, typically used internally for processing.
+ - `partialExecutionMessages`: Array holding messages generated if the execution is paused or partially completed.
+ - `tool_names`: Names of tools used in the execution, e.g., APIs or functions.
+ - `iteration`: Current iteration count in the execution loop.
+ - `injectedVariables`: Variables introduced during execution, such as results from Knowledge Base queries.
+
+- `location`: Provides information about the Autonomous Node’s current position in the Workflow:
+ - `type`: Indicates whether it's a Workflow or standalone operation.
+ - `workflowId`: Unique identifier for the Workflow.
+ - `workflowName`: Name of the Workflow where the execution takes place.
+ - `nodeId`: Identifier for the specific node within the Workflow.
+ - `nodeName`: Name of the node, e.g., `"AutonomousNode"`.
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/exporting-compiled-bot-analytics-with-the-botpress-api.mdx b/src/content/docs/studio/guides/advanced/exporting-data/exporting-compiled-bot-analytics-with-the-botpress-api.mdx
new file mode 100644
index 0000000..12a39b9
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/exporting-compiled-bot-analytics-with-the-botpress-api.mdx
@@ -0,0 +1,64 @@
+---
+title: Compiled Bot Analytics
+---
+
+import { Note } from '@/components/callouts'
+
+The Botpress Cloud dashboard provides you with an Analytics page with counters for the total number of users, new users, returning users, sessions and messages. It also shows a chart with the data and allows you to filter by date range.
+
+While this interface is great for understanding reach and engagement in a glance, you may need the data in a third-party service. Luckily, you can use the Botpress API to export the analytics data to your own database or system. Let's see how to do it.
+
+## Making a request to the API
+
+Send a `GET` request to `https://api.botpress.cloud/v1/admin/bots//analytics` adding the following header: `Authorization: Bearer `.
+
+
+Note
+
+You can find your personal access token in your [Botpress Dashboard](https://app.botpress.cloud/). Click your avatar and select "Personal Access Tokens". Generate a new one and copy it.
+
+
+
+This is how the request would look like using Axios in a JavaScript application:
+
+```ts
+const requestConfig = {
+ headers: {
+ Authorization: `Bearer ${process.env.BOTPRESS_PERSONAL_ACCESS_TOKEN}`,
+ },
+}
+
+const getAnalytics = await axios.get(`https://api.botpress.cloud/v1/admin/${botId}/analytics`, requestConfig)
+```
+
+If you were to print the analytics (available at `getAnalytics.data.records`), the result would look like this:
+
+```json
+[
+ {
+ "startDateTimeUtc": "2023-10-18T00:00:00.000Z",
+ "endDateTimeUtc": "2023-10-30T20:00:00.000Z",
+ "returningUsers": 14,
+ "newUsers": 4,
+ "sessions": 4,
+ "messages": 146
+ },
+ {
+ "startDateTimeUtc": "2023-09-01T03:00:00.000Z",
+ "endDateTimeUtc": "2023-09-31T19:00:00.000Z",
+ "returningUsers": 38,
+ "newUsers": 16,
+ "sessions": 25,
+ "messages": 1943
+ }
+]
+```
+
+
+Note
+
+It's a list of records containing the start and end date of the period, the number of returning users, new users, sessions and messages. With this information you can create your own charts and dashboards in your internal systems or favorite BI tool.
+
+
+
+If you need advanced analytics about user behavior and the paths they take when interacting with the bot, you can use the [Hooks method](/studio/concepts/hooks) to export the data in real-time to a third-party service like Mixpanel, Hotjar, Segment or Amplitude.
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/exporting-raw-conversations-with-the-botpress-api.mdx b/src/content/docs/studio/guides/advanced/exporting-data/exporting-raw-conversations-with-the-botpress-api.mdx
new file mode 100644
index 0000000..ef9e371
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/exporting-raw-conversations-with-the-botpress-api.mdx
@@ -0,0 +1,262 @@
+---
+title: Raw Conversations
+---
+
+import { Note, Info } from '@/components/callouts'
+
+The Botpress API allows you to access your bot's conversations from an external service. This is very useful if you need to manage or analyze the conversations somehow. In this tutorial we give steps to use the API for this purpose and steps to format the response data. Let's get started!
+
+
+Note
+
+Access the API documentation to verify the schema/structure of the [Conversations and Messages](/get-started/manage-your-agent/monitor#conversations) and see if the data is useful for your use case.
+
+
+
+
+Note
+
+You can find your personal access token in your [Admin Dashboard](https://app.botpress.cloud/). You can find your bot ID in the URL of your bot's dashboard, it's the letters and numbers right after `chatbots/`
+
+
+
+## 1. Getting the Conversations list from the API
+
+### Using Axios
+
+Send a `GET` request to `https://api.botpress.cloud/v1/chat/conversations` adding the following headers: `Authorization: Bearer ` and `x-bot-id: `.
+
+This is how the request would look like using Axios in a JavaScript application (e.g in a Execute Code in Botpress):
+
+```ts
+const requestConfig = {
+ headers: {
+ // Authorization header with a Bearer token for authentication.
+ Authorization: `Bearer ${process.env.BOTPRESS_PERSONAL_ACCESS_TOKEN}`,
+ // The unique identifier of the bot for which we want to retrieve conversations.
+ 'x-bot-id': process.env.BOTPRESS_BOT_ID,
+ },
+}
+
+// An empty array to store all retrieved conversations.
+const allConversations = []
+
+// Send an HTTP GET request to the specified API endpoint to get conversations.
+const getConversations = await axios.get(
+ `https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,
+ requestConfig
+)
+
+// Add the retrieved conversations to the list.
+allConversations.push(...getConversations.data.conversations)
+```
+
+### Using the Botpress Client library
+
+The same logic to get conversations but using the [Botpress Client library](https://www.npmjs.com/package/@botpress/client) in a Node.js application:
+
+```ts
+import { Client } from '@botpress/client'
+
+const client = new Client({
+ token: process.env.BOTPRESS_ACCESS_TOKEN,
+ botId: process.env.BOTPRESS_BOT_ID,
+})
+
+const allConversations = []
+
+const getConversations = await client.listConversations({
+ nextToken: paginationToken,
+})
+
+allConversations.push(getConversations.conversations)
+```
+
+
+Info
+
+The API returns a maximum of 20 conversations per request. You will need to use the `nextToken` property to fetch the next batch of conversations. The `nextToken` property is returned in the `meta` object of the response.
+
+
+
+## 2. Getting all Conversations from the API
+
+Now that you know the methods of getting the first conversations from the API, let's see how to get them. You can get them gradually or all at once, but you need to use the [pagination](/api-reference/pagination) token regardless.
+
+### Getting conversations gradually
+
+Create a function that will fetch the next batch of conversations when called. You could use a button to trigger it or trigger it automatically with infinite scroll. Pass the `nextToken` property retrieved from the first request as a parameter to the function, then update it on subsequent calls.
+
+```js
+async function loadConversations(paginationToken) {
+ const getConversations = await axios.get(
+ `https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,
+ {
+ ...requestConfig,
+ }
+ )
+
+ return getConversations.data
+ // The returned value will be an object: `{ conversations: [...], meta: { nextToken: "string" } }`
+}
+```
+
+### Getting all conversations
+
+Use a loop to fetch all conversations at once using the above logic. This isn't recommended for bots with a large number of conversations as it may take a long time to complete and may cause timeouts. The use of a library like\
+[p-retry](https://www.npmjs.com/package/p-retry) to retry requests automatically is recommended.
+
+```js
+const allConversations = []
+let paginationToken
+
+do {
+ // Send an HTTP GET request to the specified API endpoint to get conversations.
+ const getConversations = await axios.get(
+ `https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,
+ requestConfig
+ )
+
+ // Add the retrieved conversations to the list.
+ allConversations.push(...getConversations.data.conversations)
+
+ // Retrieve the token for the next set of conversations, if available.
+ paginationToken = getConversations.data.meta.nextToken
+
+ // As long as paginationToken has a value, this function will execute again
+} while (paginationToken)
+```
+
+## 3. Getting the Messages list
+
+Once you have gone through the list of conversations and found out the id of the desired conversation to export, you can then use the API to list the actual messages.
+
+In the example below we're using the [Botpress Client library](https://www.npmjs.com/package/@botpress/client) and assume the client is set up already:
+
+```js
+const conversationId = 'the desired conversation id here'
+
+const allMessages = []
+
+const getMessages = await client.listMessages({
+ conversationId,
+ nextToken: paginationToken,
+})
+
+allMessages.push(getMessages.messages)
+```
+
+You might create a loader function or a finite loop as shown above to get all the messages.\
+This is how the `allMessages` array is gonna look like:
+
+```json
+[
+ {
+ "id": "503dda87-3e54-40b6-8167-55d685a85345",
+ "createdAt": "2023-10-24T20:20:44.812Z",
+ "conversationId": "ec669jj8-e465-482d-8fbe-cb348bf81212",
+ "payload": {
+ "text": "Pick one or many from the list",
+ "options": [
+ {
+ "label": "First option",
+ "value": "First option"
+ },
+ {
+ "label": "Second option",
+ "value": "Second option"
+ }
+ ]
+ },
+ "tags": {},
+ "userId": "efc0f8e8-7e51-4458-8907-ea1e43eb8852",
+ "type": "choice",
+ "direction": "outgoing"
+ },
+ {
+ "id": "41bb8564-e7ab-4113-c3d8-5fdhh27e4c34",
+ "createdAt": "2023-10-24T20:20:49.201Z",
+ "conversationId": "ec66ffb8-e465-482d-8fbe-csd348b81212",
+ "payload": {
+ "type": "quick_reply",
+ "text": "First option",
+ "payload": "First option"
+ },
+ "tags": {
+ "webchat:id": "cc70c21b-4g24-4f5c-8f52-43a900b7b047"
+ },
+ "userId": "f96da97d-4215-447f-86e2-b9e33232e6d3",
+ "type": "quick_reply",
+ "direction": "incoming"
+ },
+ {
+ "id": "c6ee8bd6-c862-54d2-97cb-998f555d4251",
+ "createdAt": "2023-10-24T20:20:49.795Z",
+ "conversationId": "ec669dd8-e465-482d-8fty-cb3348581212",
+ "payload": {
+ "imageUrl": "https://s3.us-east-1.amazonaws.com/cloud-studio-botsbca2d219-2316w6llinepa/f4b77ea0-d597-4d3f-988d-9c66f127d542/media/2360a7bb-162b-4ed1-8551-7000fdb0f7ef.png"
+ },
+ "tags": {},
+ "userId": "efb454t5-7e51-4458-8007-ea1e43eb8852",
+ "type": "image",
+ "direction": "outgoing"
+ }
+]
+```
+
+
+Note
+
+In this example the bot sends a Multiple Choice card, then the user answers by clicking one of the options, and then the bot sends an Image card. Notice how the message payload changes according to the message type, so be mindful of that when reading the `payload` property.
+
+
+
+## 4. Formatting the Messages list
+
+Now that you have the list of messages of a conversation it's time to format it so it becomes readable. We're going to use a custom function for that:
+
+```ts
+function formatMessage(message) {
+ let messageText = ''
+
+ if (message.direction === 'incoming') {
+ messageText += 'User: '
+ } else {
+ messageText += 'Bot: '
+ }
+
+ if (message.type === 'text' || message.type === 'quick_reply') {
+ messageText += message.payload.text
+ } else if (message.type === 'choice') {
+ messageText += `${message.payload.text}: ${message.payload.options.map((option) => option.label).join(' / ')}`
+ } else {
+ messageText += `Media message of type ${message.type}`
+ }
+
+ messageText += `\n at ${new Date(message.createdAt).toLocaleString()}`
+
+ return messageText
+}
+
+const history = allMessages.map((message) => formatMessage(message)).join('\n\n')
+```
+
+The `history` string will end up looking like this:
+
+```text
+Bot: Pick one or many from the list: First Option / Second Option
+at 24/10/2023, 5:20:44 PM
+
+User: First Option
+at 24/10/2023, 5:21:00 PM
+
+Bot: Media message of type image
+at 24/10/2023, 5:21:09 PM
+```
+
+
+Note
+
+You can customize the `formatMessage` function to have different formatting or to return more information of the messages. Now use the `history` variable however you like - send it via email, add it to a Google Sheets document, send it to Botpress to do further processing, etc.
+
+
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/getting-the-conversation-history-from-within-your-bot.mdx b/src/content/docs/studio/guides/advanced/exporting-data/getting-the-conversation-history-from-within-your-bot.mdx
new file mode 100644
index 0000000..88033a2
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/getting-the-conversation-history-from-within-your-bot.mdx
@@ -0,0 +1,75 @@
+---
+title: Conversation History
+---
+
+import { Info } from '@/components/callouts'
+
+Botpress Cloud provides you with several different ways to export a conversation to external services, each one has its use cases and advantages. Let's take a look at them.
+
+## Using the Summary Agent
+
+The [Summary Agent](/studio/concepts/agents/summary-agent) listens to all new messages in the conversation to build a summary and a transcript.
+
+- The summary is available at `conversation.SummaryAgent.summary` and contains an explanation of what happened in conversation, like "The user asked for the opening hours and the bot answered by saying the business works 24/7". You can choose how detailed the summary is by setting the max tokens in the Agent settings.
+- The transcript is available at `conversation.SummaryAgent.transcript` and contains the history of the conversation going back a certain amount of turns. You can set that amount of turns in the Summary Agent settings. If you set it to 0, the transcript will contain all messages.
+
+### Advantages
+
+The `summary` variable is useful if you don't need to have many details about the conversation, especially because some of them get lengthy and if you may not want all that data. The `transcript` variable is the best way to have the full history of the conversation in a single text without needing [Hooks](/studio/concepts/hooks) or other workarounds. Using the Summary Agent for exporting conversations is also great because you have access to the history during the very conversation so you don't need to make manual or scheduled requests to our API from external services.
+
+### Disadvantages
+
+The disadvantage of using the Summary Agent for exporting conversations is that after the amount of messages surpasses the max amount of turns for the transcript, you won't have the full conversation anymore (You can mitigate this by setting the max amount to 0). Another disadvantage is that the Agent only has access to the\
+current session, so if the user is resuming a conversation, you won't have the previous messages in the history. To get the whole conversation at any moment, use the [API method for exporting conversations](/studio/guides/advanced/exporting-data/exporting-raw-conversations-with-the-botpress-api)
+
+## Using Hooks
+
+[Hooks](/studio/concepts/hooks) are functions that are executed under the hood every time there's a new message from the user or from the bot. You can create hooks that build the conversation history as it happens. They work similarly to the Summary Agent but with hooks you can customize how the history is built and there's no limitation for its size (with the exception of the 128KB max session size).
+
+### Advantages
+
+This solution is useful if you need to have all details about the conversation. It also allows you to build the history however you like - adding more information than only the message and actor.
+
+### Disadvantages
+
+The disadvantage of using Hooks is that it requires some work to set up and you only have access to the current session, so if the user is resuming a conversation, you\
+won't have the previous messages in the history. To get the whole conversation at any moment, use the [API method for exporting conversations](/studio/guides/advanced/exporting-data/exporting-raw-conversations-with-the-botpress-api)
+
+### Setting up the Hooks
+
+1. Create a hook under "Before Incoming Message" in the "Hooks" section with the following code:
+
+```ts
+if (!event.state.session.fullHistory) {
+ event.state.session.fullHistory = ''
+}
+event.state.session.fullHistory = event.state.session.fullHistory + `user: ${event.payload.text}` + '\n'
+```
+
+2. Create a hook under "Before Outgoing Message" with the following code:
+
+```ts
+if (!event.state.session.fullHistory) {
+ event.state.session.fullHistory = ''
+}
+event.state.session.fullHistory = event.state.session.fullHistory + `bot: ${outgoingEvent.payload.text}` + '\n'
+```
+
+## Sending the Conversation History
+
+Now that you have the conversation history, you can add an [Execute Code card](/studio/concepts/cards/execute-code) to manipulate the variable as you prefer, for example sending it to an API or via email:
+
+```ts
+await axios.post('https://my-api-url.com', {
+ // keep only the desired variable below
+ conversation: event.state.session.fullHistory OR conversation.SummaryAgent.summary OR conversation.SummaryAgent.transcript
+ user: user.name
+})
+```
+
+
+Info
+
+You could add this card to the [Conversation End](/studio/concepts/workflows#conversation-end) Workflow so that the full session is sent when the conversation ends. (The bot will only enter the End Workflow if there's an explicit Transition to an End node)
+
+
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/introduction.mdx b/src/content/docs/studio/guides/advanced/exporting-data/introduction.mdx
new file mode 100644
index 0000000..73ded58
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/introduction.mdx
@@ -0,0 +1,67 @@
+---
+title: Exporting Data
+description: >-
+ Export data from your bot using the Botpress API by requesting the
+ relevant endpoint.
+sidebarTitle: Introduction
+---
+
+Botpress Cloud allows you to create, manage, and deploy bots with little to no coding or infrastructure. In the natural course of maintaining a bot you may want to access its data outside of Botpress for various purposes, such as reporting, analysis, backup, or integration.
+
+This section covers some of the most important use cases for extracting bot data to third-parties software.
+
+
+
+
+ |
+ **Action**
+ |
+
+
+ **Methods**
+ |
+
+
+ **Use Cases**
+ |
+
+
+
+
+
+
+ |
+ Exporting conversations
+ |
+
+
+ [Using the Botpress API](./exporting-raw-conversations-with-the-botpress-api)
+ |
+
+
+ Data Analysis\
+ Compliance and Auditing\
+ Backup and Historical Record\
+ Debugging
+ |
+
+
+
+ |
+ Exporting analytics
+ |
+
+
+ [Using the Botpress API](./exporting-raw-conversations-with-the-botpress-api)
+ |
+
+
+ Performance Monitoring and Evaluation\
+ User Tracking and Behavior Analysis\
+ Product Management\
+ Debugging
+ |
+
+
+
+
diff --git a/src/content/docs/studio/guides/advanced/exporting-data/streaming-analytics-from-within-your-bot-with-hooks.mdx b/src/content/docs/studio/guides/advanced/exporting-data/streaming-analytics-from-within-your-bot-with-hooks.mdx
new file mode 100644
index 0000000..a8712f2
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/exporting-data/streaming-analytics-from-within-your-bot-with-hooks.mdx
@@ -0,0 +1,97 @@
+---
+title: Streaming Analytics
+---
+
+import { Note } from '@/components/callouts'
+
+The Botpress Cloud dashboard provides you with an Analytics page with counters for the total number of users, new users, returning users, sessions and messages. It also shows a chart with the data and allows you to filter by date range.
+
+While this interface is great for understanding reach and engagement in a glance, you may need more in-depth data about user behavior and the paths they take when interacting with the bot, and you may need to have this data streamed to a third-party service like Hotjar, Segment or Amplitude. Luckily, you can use the Hooks feature to do just that!.
+
+In this tutorial we're going to use Mixpanel as an example, but you can use any service that has a REST API and an endpoint to receive events.
+
+## Setting up Mixpanel
+
+1. Create an account and a project in [Mixpanel](https://mixpanel.com/).
+2. Go to your project settings and copy the Project Token.
+
+## Setting up the Hooks
+
+1. Open Botpress Studio, go to the Hooks tab and click on the `+` button next to **Before Incoming Message** to create a new hook.
+2. Name it `send-user-analytics` for example
+3. Add the following JavaScript code:
+
+```ts
+const userAnalyticsData = {
+ time: event.createdOn.getTime(), // Mixpanel event datetime
+ $insert_id: event.id, // Mixpanel unique event
+ distinct_id: event.userId, // Mixpanel preventing duplicates
+ bot_id: event.botId,
+ conversation_id: event.conversationId,
+ payload: event.payload,
+ text: event.preview,
+ current_flow: event.state.context.currentFlow,
+ current_node: event.state.context.currentNode,
+ current_card: event.state.context.currentCard,
+}
+
+const projectToken = ''
+
+await axios.post(
+ 'https://api.mixpanel.com/import',
+ [
+ {
+ event: 'Inbound Message',
+ properties: userAnalyticsData,
+ },
+ ],
+ {
+ headers: {
+ Authorization: `Basic ${btoa(projectToken + ':')}`,
+ },
+ }
+)
+```
+
+4. Click on the `+` button next to **Before Outgoing Message** to create a new hook.
+5. Name it `send-bot-analytics` for example
+6. Add the following JavaScript code:
+
+```ts
+const botAnalyticsData = {
+ time: outgoingEvent.createdOn.getTime(), // Mixpanel event datetime
+ $insert_id: outgoingEvent.id, // Mixpanel unique event
+ distinct_id: outgoingEvent.userId, // Mixpanel preventing duplicates
+ bot_id: outgoingEvent.botId,
+ conversation_id: outgoingEvent.conversationId,
+ payload: outgoingEvent.payload,
+ text: outgoingEvent.preview,
+ current_flow: outgoingEvent.state.context.currentFlow,
+ current_node: outgoingEvent.state.context.currentNode,
+ current_card: outgoingEvent.state.context.currentCard,
+}
+
+const projectToken = ''
+
+await axios.post(
+ 'https://api.mixpanel.com/import',
+ [
+ {
+ event: 'Outbound Message',
+ properties: botAnalyticsData,
+ },
+ ],
+ {
+ headers: {
+ Authorization: `Basic ${btoa(projectToken + ':')}`,
+ },
+ }
+)
+```
+
+
+Note
+
+Now every time a user or the bot sends a message, Mixpanel will be notified with the event data. You can use this data to create funnels, analyze user behavior and understand the paths they take when interacting with the bot.
+
+
diff --git a/src/content/docs/studio/guides/advanced/kitchen-sink-advanced-starter-template.mdx b/src/content/docs/studio/guides/advanced/kitchen-sink-advanced-starter-template.mdx
new file mode 100644
index 0000000..78fe8bf
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/kitchen-sink-advanced-starter-template.mdx
@@ -0,0 +1,74 @@
+---
+title: Advanced Starter Template
+---
+
+import { Picture } from 'astro:assets'
+import downloadStartGithubImg from './assets/download-start-github.png'
+import importBotImg from './assets/import-bot.png'
+
+import YouTube from '@/components/YouTube.astro'
+
+## Import Guide
+
+1. Go to the [Advanced Starter Template](https://github.com/botpress/growth/tree/master/advanced-starter-bot-template) located on the Botpress Growth Team's GitHub!
+2. Scroll down to the "How to use" section and click the download link for the [kitchen-sink.bpz](https://github.com/botpress/growth/blob/master/advanced-starter-bot-template/kitchen-sink.bpz) file.
+3. Click on the download icon on the right side of the screen (see screenshot below).
+
+
+
+4. Go to your [Botpress studio](https://studio.botpress.cloud)
+5. Click on the Botpress icon at the top left of your screen
+6. Click "Import / Export" and then click on "Import from file" (see screenshot below).
+
+
+
+7. Select this template!
+8. Enjoy!!! Please make sure to read the rest of this documentation and watch the video below!
+
+## Purpose
+
+This comprehensive template covers the core features and capabilities of Botpress, serving as both a learning resource and a foundation for your bot projects.
+
+Whether you are new to Botpress or looking to explore our features, this template provides practical, real-world examples you can learn from and adapt to your needs. Follow along with our YouTube tutorial below for a detailed walkthrough of all the features.
+
+
+
+## Core Functionalities
+
+1. **Initial User Data Loading**
+ - Capture platform-specific user data (Messenger ID, WhatsApp number, Webchat data, etc...)
+ - Handle different integration sources
+2. **Event Tracking**
+ - Custom analytics platform integration
+ - Support for Google Analytics, Mixpanel, and Segment
+ - Botpress' built-in analytics Agent.
+3. **Proactive Greeting**
+ - Bot-initiated conversations (embedded Webchat and shareable link only)
+4. **Workflow Routing System**
+ - Using a central routing node to route to other Workflows.
+ - Helps solve the question "How to transition outside of an autonomous node?"
+ - Two routing options:
+ 1. Autonomous node-based routing (AI option)
+ 2. Button-based routing (non-AI option)
+5. **Requiring Information from the User to Send to an External Tool**
+ - Required field collection (for example: requiring a valid email)
+ - External tool to send tickets or information to
+ - Botpress table integration (to send information as rows)
+6. **Querying Knowledge Base and Saving Search Results**
+ - Question and answer tracking
+ - Prevent AI hallucinations by telling the user that no answer was found if the information doesn't exist within the Knowledge Base. This bot covers fallback handling for unanswered questions.
+ - Track the exact chunk, Knowledge Base, and citation for where the information came from within your Knowledge Base.
+7. **Live Agent Handoff**
+ - Assigning a ticket to a live agent, causing the conversation with the bot to be temporarily paused until the live agent is done solving the ticket.
+ - The human can "talk through" the bot to the user.
+8. **CSAT (Customer Satisfaction) System**
+ - End-of-conversation survey
+ - Conversation summary generation and storage in Conversation Ratings Table
+9. **Table Search and Filtering**
+ - Querying from a Botpress table to fetch row(s) based on user input parameters.
+10. **Management of Multiple Sub-Bots within a Single Bot for Multi-Client Purposes**
+
+- Client-specific Knowledge Base segmentation
+- Customer tag and identity management
+- Dynamic Knowledge Base selection
+- Multi-client support within a single bot instance
diff --git a/src/content/docs/studio/guides/advanced/retention-period.mdx b/src/content/docs/studio/guides/advanced/retention-period.mdx
new file mode 100644
index 0000000..e59fad9
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/retention-period.mdx
@@ -0,0 +1,17 @@
+---
+title: Retention Period
+---
+
+import { Note } from '@/components/callouts'
+
+The retention period for your Botpress data depends on its type:
+
+| **Data type** | **Retention period** | **Notes** |
+| :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------- |
+| [Logs](/studio/concepts/debugger-logs-json#logs) | 30 days | |
+| [Conversations](/get-started/manage-your-agent/monitor#conversations) | 90 days | Can be manually deleted using the [Chat API](/api-reference/chat-api/deleteconversation) |
+| [Messages](/get-started/manage-your-agent/monitor#conversations) | 90 days | Can be manually deleted using the [Chat API](/api-reference/chat-api/deletemessage) |
+| [Events](/get-started/manage-your-agent/inspect#events) | 90 days | |
+| Files | Indefinitely, unless [created with an expiry date](/api-reference/files-api/upsertfile#body-expires-at) | Can be manually deleted using the [Files API](/api-reference/files-api/deletefile) |
+
+Other types of data are kept indefinitely unless you [delete them using one of our APIs](/api-reference/).
diff --git a/src/content/docs/studio/guides/advanced/safety/assets/bot-configuration.png b/src/content/docs/studio/guides/advanced/safety/assets/bot-configuration.png
new file mode 100644
index 0000000..4e33859
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/safety/assets/bot-configuration.png differ
diff --git a/src/content/docs/studio/guides/advanced/safety/assets/hitl.png b/src/content/docs/studio/guides/advanced/safety/assets/hitl.png
new file mode 100644
index 0000000..4474a6c
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/safety/assets/hitl.png differ
diff --git a/src/content/docs/studio/guides/advanced/safety/assets/llm-inspector.png b/src/content/docs/studio/guides/advanced/safety/assets/llm-inspector.png
new file mode 100644
index 0000000..87a1e57
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/safety/assets/llm-inspector.png differ
diff --git a/src/content/docs/studio/guides/advanced/safety/assets/rag-safety.png b/src/content/docs/studio/guides/advanced/safety/assets/rag-safety.png
new file mode 100644
index 0000000..12d2b6e
Binary files /dev/null and b/src/content/docs/studio/guides/advanced/safety/assets/rag-safety.png differ
diff --git a/src/content/docs/studio/guides/advanced/safety/brand-safety-framework.mdx b/src/content/docs/studio/guides/advanced/safety/brand-safety-framework.mdx
new file mode 100644
index 0000000..ac9d367
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/safety/brand-safety-framework.mdx
@@ -0,0 +1,76 @@
+---
+title: Brand Safety Framework
+description: >-
+ Control AI responses, enforce brand-aligned messaging, and prevent harmful
+ outputs.
+---
+
+import { Picture } from 'astro:assets'
+import botConfigurationImg from './assets/bot-configuration.png'
+import hitlImg from './assets/hitl.png'
+import llmInspectorImg from './assets/llm-inspector.png'
+import ragSafetyImg from './assets/rag-safety.png'
+
+The Brand Safety Framework in Botpress is a comprehensive suite of features designed to provide transparency and control over AI-driven decisions, ensuring brand safety across all interactions. Similar to a car's safety features—such as airbags and crash collision ratings—the framework isn't a single toggle but a holistic approach that includes several powerful tools designed to give you visibility into and control over an LLM's actions. Botpress empowers you with unparalleled insight into the logic of LLMs and equips you with the controls to adjust and refine decision-making processes, securing brand integrity in every interaction.
+
+## LLM Transparency
+
+Traditional LLMs and providers often operate as opaque black boxes, making it challenging to understand the reasoning behind their decisions. Botpress’s BSF addresses this challenge by exposing the decision-making pathways of LLMs, allowing users to see why certain outputs were generated and how they align with brand standards. The core principle is simple: when you can understand and influence an LLM’s decisions, you can protect your brand.
+
+## Key Features
+
+### Policy Agent
+
+
+
+The Policy Agent is a rules-based mechanism that controls the outputs of LLMs by enforcing constraints and guardrails. By configuring policies, users can dictate acceptable response behaviors, prevent harmful outputs, and ensure that AI actions align with brand values.
+
+##### Usage
+
+- Define constraints, including YAML or JSON configurations.
+- Set gates to filter out undesirable responses based on specific keywords, patterns, or context cues.
+- Identify policies or behaviors your agent should adhere to during conversations.
+
+### RAG Safety
+
+
+
+Retrieval-Augmented Generation (RAG) Safety provides transparency over the data selection process used by LLMs. It reveals which data chunks were identified as relevant to a query and which were ultimately submitted to the LLM. Users have the ability to review, approve, or modify these selections, ensuring that only the most appropriate data informs the AI's output.
+
+##### Usage
+
+{/* vale Botpress.workflows = NO */}
+
+- Access a visual interface that displays selected chunks with contextual relevance scores.
+- Modify data chunk selections manually or set up automated rules to refine data retrieval criteria.
+- Log and audit the data flow to track the decisions made during the query process.
+
+{/* vale Botpress.workflows = YES */}
+
+### LLM Inspector
+
+
+
+The LLM Inspector is a tool that breaks down the decision-making process of the LLM, showing why it selected certain actions or responses. By dissecting the LLM’s internal logic, users can gain insights into the decision pathways and make informed adjustments to align AI behavior with brand standards.
+
+##### Usage
+
+- Inspect decision trees that outline response logic and action selection.
+- View confidence scores, logic paths, and influence factors contributing to specific outputs.
+- Adjust weighting and influence factors to steer future decision-making processes
+
+### HITL
+
+
+
+HITL, or Human-in-the-Loop, allows you to participate in an AI agent's conversation directly from the Botpress dashboard. This feature offers a critical layer of oversight and control when using LLMs in customer- or user-facing interactions. It was designed to ensure that sensitive or high-risk conversations can be escalated to human agents, helping maintain brand integrity, mitigate potential issues, and protect user privacy.
+
+##### Usage
+
+You can use HITL to define rules or "gates" within a conversation that determine when a human agent should intervene. For example, if the conversation involves sensitive personal data, triggers specific legal language, or moves into territory that may require human expertise, the conversation is automatically handed off to a human agent for further handling.
+
+You can configure the system to identify specific keywords, scenarios, or actions that require human oversight. This level of customizability ensures that only relevant conversations are escalated, preserving efficiency while safeguarding privacy.
+
+By integrating HITL into your LLM-driven solutions, you ensure your brand remains compliant with privacy standards, while retaining the flexibility and efficiency of AI-driven interactions.
+
+This feature allows businesses to have the best of both worlds: leveraging cutting-edge AI to handle the bulk of interactions, while having the safety net of human oversight in sensitive situations. HITL enhances trust by allowing businesses to demonstrate that they're taking proactive steps to ensure conversations are handled responsibly. This creates confidence in the platform's ability to handle customer interactions without compromising privacy or brand safety.
diff --git a/src/content/docs/studio/guides/advanced/safety/introduction.mdx b/src/content/docs/studio/guides/advanced/safety/introduction.mdx
new file mode 100644
index 0000000..f813940
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/safety/introduction.mdx
@@ -0,0 +1,27 @@
+---
+title: Safety
+description: >-
+ Botpress provides a robust feature set that ensure AI-driven interactions are
+ safe, controlled, and compliant.
+sidebarTitle: Introduction
+---
+
+import Tooltip from '@/components/Tooltip.astro'
+
+Ensuring the safety of AI-driven interactions is a core priority for our team, and for bot builders. The Botpress platform is designed to empower developers while maintaining strict safety standards, giving you the tools needed to build reliable and controlled AI solutions. This overview covers the key safety aspects of Botpress, including constraint management, data privacy, access control, and mitigation of AI-related risks like hallucinations.
+
+## Key Safety Features
+
+1. **Policy Agent**: Control AI behavior with predefined rules and constraints to ensure responses align with your organization’s standards. The Policy Agent acts as a gatekeeper, enforcing guardrails and mitigating hallucinations by filtering outputs against customizable policies.
+
+2. **Access Control & Permissions**: Secure your environment with granular access control. Define roles and permissions to regulate who can view, edit, and deploy AI models, ensuring that only authorized users can make changes.
+
+3. **Data Privacy & Security**: Botpress prioritizes data security with encryption, anonymization, and secure API connections. Our platform helps you comply with privacy regulations, safeguarding sensitive information across all interactions.
+
+4. **Monitoring & Analytics**: Gain insights into AI behavior and performance through monitoring and analytics tools. Track usage patterns, detect anomalies, and adjust policies in real time to maintain optimal safety levels.
+
+5. **Error Mitigation & Recovery**: Implement fallback mechanisms that catch errors or misbehaviour, redirecting interactions to human agents or predefined safe states. This ensures continuity and reliability even when the AI is uncertain or encounters edge cases.
+
+### **Why Safety Matters**
+
+Building trust in AI systems starts with safety. By implementing robust safety measures, Botpress ensures your AI solutions aren't only effective but also secure and compliant with industry standards. Our commitment to safety helps you deploy AI with confidence, knowing that you are in control of every interaction.
diff --git a/src/content/docs/studio/guides/advanced/safety/preventing-abuse.mdx b/src/content/docs/studio/guides/advanced/safety/preventing-abuse.mdx
new file mode 100644
index 0000000..55d56b8
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/safety/preventing-abuse.mdx
@@ -0,0 +1,37 @@
+---
+title: Preventing Abuse
+---
+
+import Tooltip from '@/components/Tooltip.astro'
+import { Info } from '@/components/callouts'
+
+At Botpress, we prioritize the security and integrity of your bots by implementing a range of robust measures to counteract fraud and malicious usage. Our strategy includes:
+
+### Rate Limits {Team}
+
+Rate limits serve as a fundamental safeguard for your bot's resources. Each bot is assigned a maximum rate of messages it can process per second. For users on the "Team" plan, a higher rate limit is applied. Enterprise customers can further customize these limits to align with their specific requirements.
+
+Rate limiting prevents the excessive influx of messages, ensuring that your bot operates efficiently and consistently. This is an essential component of our abuse prevention strategy.
+
+### Allowed Origins {Team}
+
+Allowed Origins is a feature that lets you explicitly control where your bot is allowed to run by specifying a whitelist of approved domains. When deploying your bot on a website, you include only the domains that you trust, and the system automatically blocks any attempts to embed the bot from unapproved sources. This straightforward, security-first approach not only minimizes the risk of unauthorized use but also aligns with best practices for maintaining a secure, controlled deployment environment.
+
+### Web Application Firewall (WAF)
+
+Our Web Application Firewall, often referred to as WAF, is a powerful layer of defense against various cyber threats. WAF can protect your bot from Distributed Denial of Service (DDoS) attacks, SQL injection, cross-site scripting, and many other malicious activities.
+
+By using WAF, Botpress takes advantage of AWS's robust security mechanisms, which are detailed in [AWS WAF Documentation](https://docs.aws.amazon.com/waf/latest/developerguide/ddos-responding.html). This means that your bot is shielded from a wide range of web-based threats, allowing it to perform at its best without disruption.
+
+### Billing Limits
+
+To provide an additional layer of protection, you have the ability to set monthly spending limits. This feature ensures that even if an abuse attempt were to circumvent the rate limits and WAF, your financial exposure remains under control. By defining a spending limit, you can prevent unexpectedly high bills resulting from excessive bot usage.
+
+In summary, our abuse prevention strategy combines rate limits, WAF protection, and billing limits to keep your bots safe and efficient. This multi-faceted approach is designed to mitigate potential abuse scenarios and maintain the integrity of your bot's operation.
+
+
+Info
+
+You can watch the [Usage tab](/get-started/configure-your-workspace#track-usage-quotas) in the Admin Dashboard to continuously verify the usage of Botpress computational resources by your bot, ensuring that it's operating within the expected limits.
+
+
diff --git a/src/content/docs/studio/guides/advanced/tips-to-optimize-ai-cost.mdx b/src/content/docs/studio/guides/advanced/tips-to-optimize-ai-cost.mdx
new file mode 100644
index 0000000..923a438
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/tips-to-optimize-ai-cost.mdx
@@ -0,0 +1,78 @@
+---
+title: Tips to optimize AI Cost
+---
+
+## Caching AI Responses
+
+Caching is one of our most effective strategies to cut bots’ AI costs. By caching AI responses, we reduce the number of requests to the LLM provider which can reduce the cost of queries by approximately 30% saving you money without compromising the quality of interactions of the bot with your users.
+
+## Optimize your Knowledge Bases
+
+Optimizing your Knowledge Bases (KBs) can greatly influence your AI Spend since KBs are usually the biggest AI cost driver in a Botpress project.
+
+**Tip 1: Choose the Right AI Model**\
+The choice of an AI model significantly impacts cost. Since GPT-3.5 Turbo is faster & cheaper than GPT-4 Turbo, we recommend thoroughly testing your setup with GPT-3.5 Turbo before considering an upgrade to more advanced versions.
+
+Our KB Agent hybrid mode offers an excellent middle ground, as we initially use GPT-3.5 Turbo to attempt a response to a query and escalate to GPT-4 Turbo only if necessary.
+
+**Tip 2: Shield Your KB**\
+You can reduce your AI Spend by shielding your KB from unnecessary typical FAQs that don’t need AI or smart answering with a Find Records card. This is how it works: if you know that users typically ask one question and you have 50 well-known questions with their answers, you can add them to a table and query that table using a Find Records card. In case you don’t find an answer, only then should you look in a KB.
+
+**Tip 3: Properly Scope your KBs**\
+Depending on the type of information and the quantity of information that you want to add to a KB, it's usually best practice to do two things in parallel to cut AI Spend cost. First, organize your information into smaller KBs, with each KB scoped to a specific product/feature/topic. Second, drive the user through a Workflow with multiple questions to scope down your search to a specific KB; this won't only reduce the cost, but it will also yield better results.
+
+**Tip 4: Website KB Data Source vs Search the Web KB Data Source**\
+If you use a website as your KB data source but don’t make constant changes to the website that need to be reflected to your bot in real time then a good cost effective alternative is to use the Search The Web as your KB data source instead of the Website KB data source. Before making that transition, make sure to test that the performance on the questions you anticipate being asked isn't degraded with this switch.
+
+**Tip 5: Query Tables with Find Records or Execute Code card**\
+If you have a Table with data you want to query, consider using the Find Records card instead of using the Table in a KB. For those with technical expertise, executing code can be an even more cost-efficient method of querying a Table. You do so by querying the Table directly from the Execute Code card and storing the output in a Workflow variable that you can refer to later.
+
+**Tip 6: Control The Chunks**\
+By chunks I'm referring to the number of chunks that will be retrieved from the Knowledge Base to generate an answer. Generally the more chunks retrieved, the more accurate the answer—but it will take longer to generate and cost more AI tokens. Experiment with chunk size to establish the lowest amount that still leads to accurate responses.
+
+## Use Execute Code Card to lower AI Spend cost
+
+The Execute Code card can be a suitable, cost-effective replacement for some AI cards. Here are a few scenarios where you can consider using them:
+
+**Smarter Message Alternatives**\
+If you want your bot to send a different AI response for the same query every single time, you must prevent caching (see Appendix to learn how). There are scenarios where the increase in AI Spend can be justified by the improvement to the conversation experience. But this isn’t always the case.
+
+Think of something like a simple greeting that’s generated with LLMs. With each greeting you will incur an additional AI Spend cost. Is it worth it? Probably not. Fortunately, there’s a cost-effective workaround: use an array with multiple responses and a simple function to randomly fetch a value and present it.
+
+Depending on the conversation volume, the amount you save by implementing this method can be well worth the effort.
+
+**Code Execution for Simple Tasks**\
+For simple tasks, such as data reformatting or extracting information from structured data, using the Execute Code card can be more efficient, cheaper and faster than relying on an LLM.
+
+**Alternatives to Summary Agent**\
+You can use Execute Code cards to create your own transcript. Place an Execute Code card wherever you want to track the users’ and bot’s message in an array variable. Afterwards, you can use that array and feed it as context to your KB.
+
+**Simplify When Possible**\
+Opt for the simpler interaction method that accomplishes the same goal without degrading user experience. For example, if you’re interested in collecting user feedback a simple star rating system with comments will be more cost-effective than using AI to collect the same information.
+
+## Tips for AI Tasks, AI Generate Text, and Translations
+
+**Choose the Right AI Model**
+
+Choosing the right AI model is so important that it’s worth mentioning twice. Similar to KBs, the choice of an AI model significantly impacts cost when it comes to AI Tasks. Opt for GPT-3.5 Turbo for less complicated instructions. Before considering an upgrade to more advanced versions, thoroughly test your setup with this model. Remember, GPT-4 Turbo costs 20x more than GPT-3.5 Turbo. Unless the results are considerably better, opt for GPT–3.5 Turbo.
+
+In addition to the above, you can also conserve AI Spend by reducing the number of tokens consumed in each AI Task run.
+
+Our recommendation is to be conscious about decreasing this number because it will result in any additional tokens to be truncated. For example, if you limit the length to 2000 tokens and your prompt plus your output is more than 2000 tokens, then your input will be truncated accordingly.
+
+**AI Task vs AI Generate Text**\
+For simple text outputs, the AI Generate Text card uses fewer tokens and is easier to set up than the AI Task card. For tasks involving parsing information, the AI Task card outperforms the AI Generate Text card.
+
+Therefore, our recommendation is to use the AI Task card when you want to use AI to process information (for example: if you want to detect the user’s intention or if you want the AI to analyze the input). But, if you want to leverage AI to generate text, then use the AI Generate Text card instead (for example: if you want to take a KB answer and expand it or if you want to generate a question creatively).
+
+**Translations**\
+If your bot is going to be handling a high amount of multilingual conversations, consider integrating hooks with external translation services for a more cost-effective option.
+
+## How to Prevent Caching
+
+If you want to overcome caching to always get live results, you can do either of the following options:
+
+For more permanent caching prevention: add `And discard:{{Date.now()}}` in all your AI-related cards (e.g., in the AI Task prompts, in the KB context, etc.).\
+For temporary caching prevention: publish your bot and test it from an incognito window.
+
+Note: all things being equal, by removing this caching layer and not making any other changes to your bot, the AI Spend cost will increase.
diff --git a/src/content/docs/studio/guides/advanced/transition.mdx b/src/content/docs/studio/guides/advanced/transition.mdx
new file mode 100644
index 0000000..5f55714
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/transition.mdx
@@ -0,0 +1,42 @@
+---
+title: Transition
+---
+
+import { Note } from '@/components/callouts'
+
+A Transition is like a "decision point" in a conversation with a bot, where the bot has to decide what to do next based on what the user has said or done. It's like a set of instructions that the bot follows to determine which "path" to take in the conversation.
+
+The transition statement is what tells the bot which response or question to provide based on what the user has said or done.
+
+## Expression
+
+An Expression transition is a conditional statement that tells the bot which node should be processed next if the condition is met. It uses generative AI to generate the conditions using plain text.
+
+This type of transition allows you to check user input, user variables, Workflow variables, and even create advanced JavaScript expressions to determine which node the bot should transition to next.
+
+You can use a combination of these checks to create complex conditions that will determine which node the bot will transition to next.
+
+
+**Generative AI Transitions**
+
+You can use generative AI to generate your conditions using plain text. In order to achieve what you exactly want, here are some examples that should guide you, but you aren't limited to it:
+
+
+
+### Always transition to another node
+
+There are two ways to make sure that a transition always triggers:
+
+The recommended approach is to click and drag starting from the circle on the bottom-right of nodes, next to the "Add Card" button. Transitions created this way always trigger when the user reaches the end of the node.
+
+You can also add an Expression card by creating an `Expression Transition` with the label "Always" and by pressing `Enter`. The code generator will insert `true` in the expression input. Anything below this `Transition` in the `Node` will never run.
+
+## Intent
+
+An Intent transition allows you to create an inline intent (or node-specific intent). Only if this intent is elected will the condition be met.
+
+This type of transition is useful when you want to create a specific response for a particular intent. You can create an\
+intent for a specific node, and the bot will transition to that node only if that intent is detected in the user's message.
+
+For example, if a user says "I want to book a hotel room," the bot can transition to a node that's specific to handling\
+hotel room bookings.
diff --git a/src/content/docs/studio/guides/advanced/use-code.mdx b/src/content/docs/studio/guides/advanced/use-code.mdx
new file mode 100644
index 0000000..a61cdbe
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/use-code.mdx
@@ -0,0 +1,70 @@
+---
+title: Using code in Studio
+---
+
+import { Tip, Warning } from '@/components/callouts'
+
+You can **write custom code to interact with your bot programmatically** in many areas of Botpress Studio.
+
+
+ Wherever you write custom code in Studio, you can access the [event object's
+ properties](/studio/guides/advanced/event-properties) to get information about the last event in your bot's operation.
+
+
+## Language
+
+You can use [TypeScript](https://www.typescriptlang.org) or regular [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) for custom code.
+
+## Where you can use code
+
+Depending on your needs, you have a few options on where to write code in Studio. Here's a cheat sheet:
+
+| Option | Executes | Reusable | Example |
+| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------- | ----------------------------------------------------------------------------- |
+| [Actions](/studio/concepts/actions) | When an [Autonomous Node](/studio/concepts/nodes/autonomous-node) decides to (based on the conversation's context) | ✅ | Make an API call to a weather service whenever the user asks for the weather |
+| [Execute Code Cards](/studio/concepts/cards/execute-code) | At a specific point in a [Workflow](/studio/concepts/workflows) | ❌ | Perform a one-time operation on some data provided by a user |
+| [Hooks](/studio/concepts/hooks) | At a specific stage of the bot's operation | ✅ | Every time a bot responds, add the total AI spend for its response to a table |
+
+Check out each section below for a more detailed breakdown:
+
+### Actions
+
+[Actions](/studio/concepts/actions) are reusable code snippets that only [Autonomous Nodes](/studio/concepts/nodes/autonomous-node) can use.
+
+Use Actions when:
+
+- You need to execute a piece of code more than once
+- You want AI to decide when to execute your code
+
+### Execute Code Cards
+
+[Execute Code Cards](/studio/concepts/cards/execute-code) execute a one-time piece of code at some point in a [Workflow](/studio/concepts/workflows). They're not reusable and can't be added to an Autonomous Node.
+
+Use Execute Code Cards when:
+
+- You only need to execute a piece of code in one place
+- You want complete control over when the code executes
+
+### Hooks
+
+[Hooks](/studio/concepts/hooks) execute code at specific stages of your bot's operation, like before every user message or after every conversation ends. They operate separately from your bot's conversational logic—when you create a Hook, it always executes at the same stage, no matter what changes you make to your Workflow.
+
+Use Hooks when:
+
+- You need to execute a piece of code every time your bot reaches a certain stage of its operation
+- You need access to information about the Autonomous Node's iteration or the current turn's metadata
+
+## Libraries
+
+The following libraries come pre-installed in the Studio's code editor:
+
+| Name | Description | Usage |
+| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------- |
+| [Axios](https://axios-http.com/docs/intro) | HTTP client for making API requests. | Available globally as `axios` |
+| [Lodash](https://lodash.com) | Utility library for data manipulation. | Available globally as `_` |
+| [Luxon](https://moment.github.io/luxon/#/) | Library for date/time manipulation. | Available globally as `luxon` |
+| [`botpress/client`](https://www.npmjs.com/package/@botpress/client) | Official Botpress HTTP client to query the [Botpress API](/api-reference). | Available globally as `client` |
+| [`bpinternal/zui`](https://www.npmjs.com/package/@bpinternal/zui) | A fork of [Zod](https://zod.dev) with additional features. | Available globally as `z` / `zui` |
+| [`botpress/zai`](https://www.npmjs.com/package/@botpress/zai) | Botpress utility library that uses AI to manipulate and generate Zui schemas and objects. | Available globally as `zai` |
+
+You can't import external libraries into the Studio's code editor.
diff --git a/src/content/docs/studio/guides/advanced/v12.mdx b/src/content/docs/studio/guides/advanced/v12.mdx
new file mode 100644
index 0000000..3706d3c
--- /dev/null
+++ b/src/content/docs/studio/guides/advanced/v12.mdx
@@ -0,0 +1,44 @@
+---
+title: Botpress v12 (and self-hosted versions)
+sidebarTitle: Botpress v12
+---
+
+import Accordion from '@/components/Accordion.astro'
+import AccordionGroup from '@/components/AccordionGroup.astro'
+import { Warning } from '@/components/callouts'
+
+
+ Botpress v12 **has been officially sunset** and is no longer available for purchase, download, or new deployments.
+ This includes all other self-hosted or locally installed versions of Botpress (including those available for Microsoft
+ Windows and other platforms),
+
+
+## Existing customers
+
+Current customers with active Botpress v12 subscriptions remain fully supported. If you are an existing customer and have questions about your subscription or deployment, please reach out directly to your dedicated account manager for assistance.
+
+## Moving forward with Botpress Cloud
+
+All new users should use [Botpress Cloud](https://app.botpress.cloud), the fully managed web application, which represents the future of the Botpress platform. Botpress Cloud provides continuous improvements, security, and scalability without the need for local installation or maintenance.
+
+## FAQ
+
+
+
+ No. Botpress v12 and all self-hosted versions are no longer available for download, purchase, or new deployments.
+
+
+ You remain fully supported. Please contact your dedicated account manager for any questions regarding your subscription or deployment.
+
+
+
+ All new development should be done in [Botpress Cloud](https://app.botpress.cloud).
+
+
+
diff --git a/src/content/docs/studio/guides/how-to/assets/an-transition-dark.png b/src/content/docs/studio/guides/how-to/assets/an-transition-dark.png
new file mode 100644
index 0000000..4a81d16
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/an-transition-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/an-transition.png b/src/content/docs/studio/guides/how-to/assets/an-transition.png
new file mode 100644
index 0000000..c166b0c
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/an-transition.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/current-ids-dark.png b/src/content/docs/studio/guides/how-to/assets/current-ids-dark.png
new file mode 100644
index 0000000..02c8f7f
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/current-ids-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/current-ids.png b/src/content/docs/studio/guides/how-to/assets/current-ids.png
new file mode 100644
index 0000000..97c5e0b
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/current-ids.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/delivery-status-dark.png b/src/content/docs/studio/guides/how-to/assets/delivery-status-dark.png
new file mode 100644
index 0000000..e8cdd4a
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/delivery-status-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/delivery-status.png b/src/content/docs/studio/guides/how-to/assets/delivery-status.png
new file mode 100644
index 0000000..0d75a2b
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/delivery-status.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/execute-code-dark.png b/src/content/docs/studio/guides/how-to/assets/execute-code-dark.png
new file mode 100644
index 0000000..a0d57c7
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/execute-code-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/execute-code.png b/src/content/docs/studio/guides/how-to/assets/execute-code.png
new file mode 100644
index 0000000..51e2a48
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/execute-code.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/fixed-schedule-dark.png b/src/content/docs/studio/guides/how-to/assets/fixed-schedule-dark.png
new file mode 100644
index 0000000..ddaecc4
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/fixed-schedule-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/fixed-schedule.png b/src/content/docs/studio/guides/how-to/assets/fixed-schedule.png
new file mode 100644
index 0000000..819c865
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/fixed-schedule.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/gpt-4-1-dark.png b/src/content/docs/studio/guides/how-to/assets/gpt-4-1-dark.png
new file mode 100644
index 0000000..962dabf
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/gpt-4-1-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/gpt-4-1.png b/src/content/docs/studio/guides/how-to/assets/gpt-4-1.png
new file mode 100644
index 0000000..f491094
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/gpt-4-1.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/model-change-logs-dark.png b/src/content/docs/studio/guides/how-to/assets/model-change-logs-dark.png
new file mode 100644
index 0000000..a5c7e1d
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/model-change-logs-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/model-change-logs.png b/src/content/docs/studio/guides/how-to/assets/model-change-logs.png
new file mode 100644
index 0000000..0f8c7fa
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/model-change-logs.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/name-and-description.png b/src/content/docs/studio/guides/how-to/assets/name-and-description.png
new file mode 100644
index 0000000..3a84114
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/name-and-description.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/new-convo-modal.png b/src/content/docs/studio/guides/how-to/assets/new-convo-modal.png
new file mode 100644
index 0000000..50fe937
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/new-convo-modal.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/oauth-bot-auth.png b/src/content/docs/studio/guides/how-to/assets/oauth-bot-auth.png
new file mode 100644
index 0000000..d4aa0c4
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/oauth-bot-auth.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/table-dark.png b/src/content/docs/studio/guides/how-to/assets/table-dark.png
new file mode 100644
index 0000000..a2bb314
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/table-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/table-full-dark.png b/src/content/docs/studio/guides/how-to/assets/table-full-dark.png
new file mode 100644
index 0000000..2be96c2
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/table-full-dark.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/table-full.png b/src/content/docs/studio/guides/how-to/assets/table-full.png
new file mode 100644
index 0000000..6f6e684
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/table-full.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/table.png b/src/content/docs/studio/guides/how-to/assets/table.png
new file mode 100644
index 0000000..cf75476
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/table.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/today-label.png b/src/content/docs/studio/guides/how-to/assets/today-label.png
new file mode 100644
index 0000000..d3d5c72
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/today-label.png differ
diff --git a/src/content/docs/studio/guides/how-to/assets/translate-composer.png b/src/content/docs/studio/guides/how-to/assets/translate-composer.png
new file mode 100644
index 0000000..e4c0aab
Binary files /dev/null and b/src/content/docs/studio/guides/how-to/assets/translate-composer.png differ
diff --git a/src/content/docs/studio/guides/how-to/different-an-models.mdx b/src/content/docs/studio/guides/how-to/different-an-models.mdx
new file mode 100644
index 0000000..9d2e502
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/different-an-models.mdx
@@ -0,0 +1,136 @@
+---
+title: Use different LLM for Autonomous Nodes
+---
+
+import { Picture } from 'astro:assets'
+import anTransitionDarkImg from './assets/an-transition-dark.png'
+import anTransitionImg from './assets/an-transition.png'
+import currentIdsDarkImg from './assets/current-ids-dark.png'
+import currentIdsImg from './assets/current-ids.png'
+import gpt41DarkImg from './assets/gpt-4-1-dark.png'
+import gpt41Img from './assets/gpt-4-1.png'
+import modelChangeLogsDarkImg from './assets/model-change-logs-dark.png'
+import modelChangeLogsImg from './assets/model-change-logs.png'
+
+import { Check, Info, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+import Icon from '@/components/Icon.astro'
+
+
+ You can now [override default LLMs directly in your Autonomous Node's settings](/studio/concepts/nodes/autonomous-node#override-default-models).
+
+This method is simpler and recommended for most use cases. The guide below remains available for advanced use cases.
+
+
+
+You can configure [Autonomous Nodes](/studio/concepts/nodes/autonomous-node) to use a different LLM than the default model specified in your [Bot Settings](/studio/concepts/bot-settings#autonomous-language-model). This is useful if your bot needs a higher-performing model for certain tasks.
+
+
+
+You will need:
+
+- A [published bot](/get-started/quick-start)
+- A [Workflow](/studio/concepts/workflows) containing more than one Autonomous Node
+- Familiarity with JavaScript
+
+
+
+## Step 1: Find the Node, Workflow and model IDs
+
+First, you need to find:
+
+- The ID of the Autonomous Node whose model you want to change
+- The ID of the Workflow containing that Autonomous Node
+- The ID of the model you want to change to
+
+### Node and Workflow IDs
+
+1. Start a conversation with your bot in the [Emulator](/studio/concepts/emulator).
+2. Continue until the bot transitions to the Autonomous Node whose model you want to change:
+
+
+
+
+
+
+3. Select one of your messages from after the bot transitioned to the new Autonomous Node. Then, open the [JSON tab](/studio/concepts/debugger-logs-json#json) in the bottom panel.
+4. Under **Payload**, navigate to `state > context`:
+
+
+
+
+
+
+5. Copy the values of `currentFlow` and `currentNode`—these are your Workflow's ID and Autonomous Node's ID.
+
+### Model ID
+
+1. Return to your conversation in the Emulator.
+2. Select ** Inspect** on any message generated by the Autonomous Node whose model you want to change.
+3. Select **View Raw ** in the upper-right corner.
+4. Navigate to `context > options > models`.
+5. Find the model you want to switch to. Expand it, then copy its full `id`. For example, for GPT-4.1:
+
+
+
+
+
+
+## Step 2: Add a Hook to change models
+
+1. In the Studio, navigate to the [Hooks](/studio/concepts/hooks) section.
+2. Select **Create Hook** and set its type to [Before LLMz Execution](/studio/concepts/hooks#before-llmz-execution).
+3. Paste the following code into the Hook:
+
+```js highlight={6-7, 15}
+// Get the current Workflow and Node IDs
+const flowID = event?.state?.context?.currentFlow ?? ''
+const nodeID = event?.state?.context?.currentNode ?? ''
+
+// Check if they match the ones we're targeting
+const flowMatches = flowID.includes('yourWorkflowID') // Replace with your own
+const nodeMatches = nodeID.includes('yourNodeID') // Replace with your own
+
+console.log('Current model: ', context.model)
+console.log('Current Workflow: ', flowID.toUpperCase())
+console.log('Current Node: ', nodeID.toUpperCase())
+
+// Switch models if they match
+if (flowMatches && nodeMatches) {
+ context.model = 'yourModelChoice' // Replace with your desired model
+ console.log('Switched to ', context.model)
+}
+```
+
+- Replace `yourWorkflowID` and `yourNodeID` with [your actual IDs](#node-and-workflow-ids).
+- Replace `yourModelChoice` with the [actual model ID](#model-id).
+
+
+ Now, this Autonomous Node will use a different model than the default model specified in your [Bot
+ Settings](/studio/concepts/bot-settings#autonomous-language-model).
+
+
+## Troubleshooting
+
+Here are some troubleshooting tips:
+
+### State is undefined
+
+If the `state` property from [Step 1](#node-and-workflow-ids) is `undefined`, make sure you're viewing your own message's logs—not the Autonomous Node's.
+
+### Check if IDs matched
+
+You can check if the Node and Workflow IDs matched by checking your bot's [logs](/studio/concepts/debugger-logs-json) after transitioning to the Autonomous Node in the Emulator:
+
+
+
+
+
+
+### Check if model actually changed
+
+To check if the model actually changed:
+
+1. Select ** Inspect** on any response from the target Autonomous Node.
+2. Select **View Raw ** in the upper-right corner.
+3. Navigate to `context > options > model`. This will display model the Autonomous Node used for the response.
diff --git a/src/content/docs/studio/guides/how-to/dropdown-menus.mdx b/src/content/docs/studio/guides/how-to/dropdown-menus.mdx
new file mode 100644
index 0000000..beb3b36
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/dropdown-menus.mdx
@@ -0,0 +1,108 @@
+---
+title: Send options as a dropdown menu
+---
+
+import { Tip, Check, Info, Warning } from '@/components/callouts'
+
+You can present options as a dropdown instead of buttons. This guide covers the built-in behaviour with [Capture Information](/studio/concepts/cards/capture-information) and an approach using code when you need a dropdown with fewer than six options.
+
+
+ You will need:
+
+ - A [published bot](/get-started/quick-start)
+ - Familiarity with JavaScript if you use [method 2](#method-2-manual-dropdown-execute-code)
+
+
+
+
+ The approach and styling in this guide are designed to work with [Webchat](/webchat/get-started/quick-start)'s choice
+ components. If your bot is deployed on a different channel, you may need to modify the approach to work with that
+ channel's components. Check out the [integrations](/integrations/get-started/introduction) section for more
+ information.
+
+
+## Method 1: Automatic dropdown (Capture Information)
+
+1. Add a [Capture Information](/studio/concepts/cards/capture-information) Card to your [Workflow](/studio/concepts/workflows). Set the field type to **Single Choice** or **Multiple Choice**
+2. Add your options inside the Card under **Choices**.
+
+If you add more than five options, they are shown as a dropdown (list) instead of buttons. (The exact threshold can vary slightly by channel. See [Choices](/studio/concepts/cards/capture-information#choices) on the Capture Information page.)
+
+This is the simplest approach when you have enough options to trigger the dropdown UI.
+
+## Method 2: Manual dropdown (Execute Code)
+
+To show a dropdown even when you have five or fewer options, or to build the option list in code, send a message with `type: 'dropdown'` from an [Execute Code](/studio/concepts/cards/execute-code) Card.
+
+### Send the dropdown message
+
+```javascript
+await client.createMessage({
+ userId: event.botId,
+ conversationId: event.conversationId,
+ tags: {},
+ type: 'dropdown',
+ payload: {
+ text: 'Select an item:', // Shown above the control
+ options: [
+ { label: 'Dropdown 1', value: 'dd1' },
+ { label: 'Dropdown 2', value: 'dd2' },
+ ],
+ },
+})
+```
+
+1. **`payload.text`**: Label or instruction shown with the control.
+2. **`payload.options`**: Each entry is `{ label: string, value: string }`.
+ 1. **`label`**: Text the user sees (for example, a product name).
+ 2. **`value`**: Value stored or matched in logic (for example, a SKU). They can match or differ.
+
+
+ In an Execute Code Card, you can read context from the [event object](/studio/guides/advanced/event-properties).
+
+
+### Complete the Workflow after the dropdown
+
+After the dropdown is sent, the user will select an option. Here are some typical ways to handle this:
+
+1. Add a [Wait for User Input](/studio/concepts/cards/capture-information#wait-for-user-input) Card so the Workflow pauses until the user interacts
+
+2. Use an [Expression Card](/studio/concepts/cards/flow-logic#expression) (or similar) to evaluate their response by checking `event.payload.value`
+
+3. Use an **Execute Code** Card to store their choice. For example:
+
+ ```javascript
+ workflow.varName = event.payload.value
+ ```
+
+ Remember to [create a Workflow variable](/studio/concepts/variables/scopes/workflow) (for example `varName`, type **String**) and grant access in code as needed ([variables in code](/studio/concepts/variables/in-code)).
+
+Wire these cards in order in the same Node (or connected Nodes) so the bot always waits, validates, then saves before continuing.
+
+## Customize the placeholder text (CSS)
+
+Classes for styling dropdowns are listed under **Use custom styles** on the [appearance settings](/webchat/get-started/configure-your-webchat#use-custom-styles) page.
+
+To replace the default **Select…** style label with your own, add custom CSS under **Bot Appearance** → **Styles** in the Studio, for example:
+
+```css
+/* Hide the original "Select..." text */
+.bpMessageBlocksDropdownButtonText {
+ font-size: 0;
+ color: transparent;
+}
+
+.bpMessageBlocksDropdownButtonText::before {
+ content: 'Choose an option...';
+ font-size: 0.8rem;
+ color: #7e7c7c;
+}
+```
+
+Adjust `content`, `font-size`, and `color` to match your brand.
+
+
+ You can rely on **Capture Information** for dropdowns when you have more than five choices, or use `createMessage`
+ with `type: 'dropdown'` in an Execute Code Card whenever you need a dropdown with fewer options or custom `label` and
+ `value` pairs.
+
diff --git a/src/content/docs/studio/guides/how-to/how-to-setup-oauth-with-github-in-botpress-using-integrations.mdx b/src/content/docs/studio/guides/how-to/how-to-setup-oauth-with-github-in-botpress-using-integrations.mdx
new file mode 100644
index 0000000..60485c6
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/how-to-setup-oauth-with-github-in-botpress-using-integrations.mdx
@@ -0,0 +1,277 @@
+---
+title: Adding user authentication to your bot via OAuth
+---
+
+import { Picture } from 'astro:assets'
+import oauthBotAuthImg from './assets/oauth-bot-auth.png'
+
+import YouTube from '@/components/YouTube.astro'
+
+OAuth can be very useful especially in cases where validating the identify of the user is crucial. In the example that follows we walk through how we was able to setup OAuth verification with GitHub as my platform of choice in our Botpress bot.
+
+This was accomplished with the help of a custom integration for setting up OAuth with GitHub.
+
+## Demo
+
+**When the user is authenticated**
+
+
+
+**When the user is unauthenticated**
+
+
+
+## Bot Setup
+
+The bot setup is straightforward. First, the user is prompted to log in by clicking on a link generated by the integration. Once the login is successful, an event is emitted. This event is captured by a trigger node, which then hands off control to an autonomous node.
+
+
+
+## Integration
+
+The integration has a couple of responsibilities:
+
+1. Generating the OAuth link that users will click on.
+2. Capturing a successful authentication which then emits an event containing the conversation ID and data about the authenticated user.
+
+This is achieved using an action ( here called “Generate OAuth2 URL” ) and the integration’s Botpress webhook handler. The webhook captures successful authentication and emits a Botpress event ( in this case, “User Authenticated” ).
+
+### Writing this integration
+
+You can use the [Building](doc:building-integrations) to bootstrap an integration, then add the following code as a starting point to achieve the above result. Once you get it working, we suggest you modify the integration to fit your purposes.
+
+In `integration.definition.ts` we define the events (which bot builders can hook onto in the Studio), and actions which allow for generating the URL that should be displayed to the end user.
+
+```typescript integration.definition.ts
+import { conversation, IntegrationDefinition, z } from '@botpress/sdk'
+import { integrationName } from './package.json'
+import { DEFAULT_STORE_KEY } from 'src/store'
+
+export default new IntegrationDefinition({
+ name: integrationName,
+ version: '0.0.1',
+ readme: 'hub.md',
+ icon: 'icon.svg',
+ configuration: {
+ schema: z.object({
+ clientId: z.string(),
+ clientSecret: z.string(),
+ state: z.string().default('secure_random_string').hidden(), // This is used for the authentication handshake, you can change it to a random string.
+ }),
+ },
+ events: {
+ onUserAuthenticated: {
+ title: 'User Authenticated',
+ description: 'Fires when a user has been authenticated',
+ schema: z.object({
+ userData: z.any(),
+ conversationIdxx: z.string(),
+ }),
+ },
+ },
+ actions: {
+ generateUrl: {
+ title: 'Generate OAuth2 URL',
+ description: 'Generates an OAuth2 URL to authenticate the user',
+ input: {
+ schema: z.object({
+ conversationId: z.string().default('{{event.conversationId}}').hidden(),
+ }),
+ },
+ output: {
+ schema: z.object({
+ url: z.string(),
+ }),
+ },
+ },
+ },
+ states: {
+ [DEFAULT_STORE_KEY]: {
+ type: 'integration',
+ schema: z.object({
+ bpWebhookUrl: z.string(),
+ conversationId: z.string(),
+ }),
+ },
+ },
+})
+```
+
+In src/index.ts is the main logic for generating a shareable sign-up URL for OAuth, and a handler method to handle the OAuth response.
+
+```typescript index.ts
+import * as sdk from '@botpress/sdk'
+import * as bp from '.botpress'
+import { Store } from './store'
+
+export default new bp.Integration({
+ register: async ({ webhookUrl, client, ctx }) => {
+ const store = new Store(client, ctx)
+ await store.initialize({
+ bpWebhookUrl: webhookUrl,
+ conversationId: '',
+ })
+ console.log('Integration registered')
+ },
+ unregister: async () => {},
+ actions: {
+ generateUrl: async ({ client, input, ctx }) => {
+ const store = new Store(client, ctx)
+ await store.load()
+
+ await store.set('conversationId', input.conversationId)
+ const webhookUrl = await store.get('bpWebhookUrl')
+
+ const clientId = ctx.configuration.clientId
+ const redirectUri = webhookUrl // Redirect back to the integration
+ const state = ctx.configuration.state // For CSRF protection
+ const scope = 'read:user' // Request access to read user profile
+
+ const githubOAuthUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(
+ redirectUri
+ )}&scope=${scope}&state=${state}`
+
+ return { url: githubOAuthUrl }
+ },
+ },
+ channels: {},
+ handler: async ({ req, client, ctx }) => {
+ const store = new Store(client, ctx)
+ await store.load()
+ const webhookUrl = await store.get('bpWebhookUrl')
+
+ // Construct a URLSearchParams object
+ const params = new URLSearchParams(req.query)
+
+ // Extract query parameters
+ const code = params.get('code') // Extract 'code'
+ const sec_string = params.get('state') // Extract 'state'
+
+ // Verify the `state` to protect against CSRF
+ if (sec_string !== ctx.configuration.state) {
+ return { status: 403, message: 'Invalid state' }
+ }
+
+ // Exchange the code for an access token
+ const tokenResponse: any = await fetch('https://github.com/login/oauth/access_token', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
+ body: JSON.stringify({
+ client_id: ctx.configuration.clientId,
+ client_secret: ctx.configuration.clientSecret,
+ code,
+ redirect_uri: webhookUrl,
+ }),
+ }).then((res) => res.json())
+
+ // Fetch user data
+ const userData: any = await fetch('https://api.github.com/user', {
+ headers: {
+ Authorization: `Bearer ${tokenResponse.access_token}`,
+ },
+ }).then((res) => res.json())
+
+ // Send a message to the user
+ const conversationId = await store.get('conversationId')
+
+ await client.createEvent({
+ type: 'onUserAuthenticated',
+ conversationId: conversationId,
+ payload: {
+ conversationIdxx: conversationId,
+ userData: userData,
+ },
+ })
+
+ return { status: 200, message: 'Success' }
+ },
+})
+```
+
+In src/store.ts we add some logic to be able to save authentication parameters which will help us know who is who when getting a callback request from OAuth.
+
+```typescript store.ts
+import * as sdk from '@botpress/sdk'
+
+export const DEFAULT_STORE_KEY = 'globalStore'
+
+export class Store {
+ private client: sdk.IntegrationSpecificClient
+ private ctx: sdk.IntegrationContext
+ private globalStoreKey: string
+ private validKeys: string[] = []
+
+ constructor(
+ client: sdk.IntegrationSpecificClient,
+ ctx: sdk.IntegrationContext,
+ globalStoreKey = DEFAULT_STORE_KEY
+ ) {
+ this.client = client
+ this.ctx = ctx
+ this.globalStoreKey = globalStoreKey
+ }
+
+ private async fetchGlobalStore(): Promise> {
+ const result = await this.client.getState({
+ type: 'integration',
+ id: this.ctx.integrationId,
+ name: this.globalStoreKey,
+ })
+ return result.state.payload || {} // Default to an empty object if no state exists
+ }
+
+ private async updateGlobalStore(store: Record): Promise {
+ console.log('updating store', store)
+ await this.client.setState({
+ type: 'integration',
+ id: this.ctx.integrationId,
+ name: this.globalStoreKey,
+ payload: store,
+ })
+ }
+
+ async initialize(initialState: Record): Promise {
+ this.validKeys = Object.keys(initialState)
+ await this.updateGlobalStore(initialState)
+ }
+
+ async load(): Promise {
+ const store = await this.fetchGlobalStore()
+ this.validKeys = Object.keys(store)
+ }
+
+ private validateKey(key: string): void {
+ if (!this.validKeys.includes(key)) {
+ throw new Error(`Key ${key} isn't a valid key, valid keys are: ${this.validKeys.join(', ')}`)
+ }
+ }
+
+ async set(key: string, value: any): Promise {
+ this.validateKey(key)
+ const store = await this.fetchGlobalStore()
+ console.log('got store', store)
+ store[key] = value // Update the key in the global store
+ await this.updateGlobalStore(store) // Save the updated store back
+ }
+
+ async get(key: string): Promise {
+ this.validateKey(key)
+ const store = await this.fetchGlobalStore()
+ return store[key] // Retrieve the value for the key
+ }
+}
+```
+
+
+
+After adding this code, deploy it to the bot you want to work on, and configure it using GitHub parameters (or whatever platform you'd like to port this to) and hit "Save Configuration".
+
+If you'd like to try out the GitHub example above, you can use this link to create the credentials :
+
+[https://github.com/settings/developers#oauth-apps](https://github.com/settings/developers#oauth-apps)
+
+{/* vale Botpress.workflows = NO */}
+The "Authorization callback URL" should be your webhook URL, located in the configuration page of the integration. There is no need to enable the device flow.
+{/* vale Botpress.workflows = YES */}
+
+That's it, now you can publish your bot, and try it out. Once that works, feel free to use this code as a starting point for your OAuth Integration.
diff --git a/src/content/docs/studio/guides/how-to/send-reminders.mdx b/src/content/docs/studio/guides/how-to/send-reminders.mdx
new file mode 100644
index 0000000..133fe96
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/send-reminders.mdx
@@ -0,0 +1,101 @@
+---
+title: Send reminders to conversations
+---
+
+import { Picture } from 'astro:assets'
+import executeCodeDarkImg from './assets/execute-code-dark.png'
+import executeCodeImg from './assets/execute-code.png'
+import fixedScheduleDarkImg from './assets/fixed-schedule-dark.png'
+import fixedScheduleImg from './assets/fixed-schedule.png'
+
+import { Check, Info } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+You can have your bot send a message to all your users' active conversations at regular intervals. This is useful if you want to send reminders, notifications, or other time-sensitive messages to your users.
+
+
+ You will need:
+
+ - A [published bot](/get-started/quick-start)
+
+
+
+## Step 1: Setup your Personal Access Token
+
+Since you need to use the Botpress API to send a reminder to all users, you need to set up a Personal Access Token (PAT) for authentication.
+
+### Create the token
+
+1. In the upper-right corner of your workspace, select your profile picture.
+2. Select **Account Settings > Access Tokens > Personal access tokens** > **Generate new token.**
+3. Enter a note to remember the token's purpose—like "Reminders".
+4. Select **Generate Token**.
+5. Copy the generated token and store it somewhere—once you leave this page, you won't be able read it again.
+
+### Store the token in a variable
+
+Next, [create a configuration variable](/studio/concepts/variables/scopes/configuration#create-a-configuration-variable) called `PERSONAL_ACCESS_TOKEN` and store your token in it. This will let you access the token in code.
+
+## Step 2: Add a Fixed Schedule Trigger
+
+Add a [Fixed Schedule](/studio/concepts/cards/fixed-schedule) Trigger to your bot's [Workflow](/studio/concepts/workflows). This will make sure your reminder sends on a set interval.
+
+
+
+
+
+
+You can configure the Trigger to execute at whatever interval you'd like.
+
+## Step 3: Add an Execute Code Card
+
+Connect an [Execute Code](/studio/concepts/cards/execute-code) Card to your Trigger:
+
+
+
+
+
+
+## Step 4: Apply the custom code
+
+Paste the following code into the Card's configuration:
+
+```javascript
+const botId = '' // Replace with your actual bot ID (found in the Studio URL)
+const botpressApiUrl = 'https://api.botpress.cloud/v1/chat/conversations'
+const botpressApiKey = env.PERSONAL_ACCESS_TOKEN
+
+const response = await axios.get(botpressApiUrl, {
+ headers: {
+ Authorization: `Bearer ${botpressApiKey}`,
+ 'x-bot-id': botId,
+ },
+})
+
+// Optional: Log the list of conversations
+console.log(response.data)
+
+response.data.conversations.forEach((conversation) => {
+ const conversationId = conversation.id
+ client.createMessage({
+ conversationId,
+ userId: botId,
+ tags: {},
+ type: 'text',
+ payload: {
+ text: "Don't forget to drink water!", // Your reminder message
+ },
+ })
+})
+```
+
+Be sure to replace the placeholder value for `botId` with your actual bot ID. To find your bot ID:
+
+1. Open your bot in the Studio.
+2. Get the bot ID from the URL's path. For example:
+ `https://studio.botpress.cloud/THIS_IS_YOUR_BOT_ID/`
+
+
+ Once you've published the latest version of your bot, it will send reminders to all active conversations at the
+ specified interval.
+
diff --git a/src/content/docs/studio/guides/how-to/track-ai-spend-in-table.mdx b/src/content/docs/studio/guides/how-to/track-ai-spend-in-table.mdx
new file mode 100644
index 0000000..e3dc2c0
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/track-ai-spend-in-table.mdx
@@ -0,0 +1,125 @@
+---
+title: Track AI spend in a table
+---
+
+import { Picture } from 'astro:assets'
+import tableDarkImg from './assets/table-dark.png'
+import tableFullDarkImg from './assets/table-full-dark.png'
+import tableFullImg from './assets/table-full.png'
+import tableImg from './assets/table.png'
+
+import { Check, Info, Warning } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+You can store data about your bot's AI spend in a table that automatically updates throughout all your bot's conversations. This includes cost from any of your bot's AI usage, including:
+
+- [Autonomous Nodes](/studio/concepts/nodes/autonomous-node)
+- [AI Cards](/studio/concepts/cards/ai/introduction)
+- Queries to a [Knowledge Base](/studio/concepts/knowledge-base/introduction)
+
+
+ You will need:
+
+ - A [published bot](/get-started/quick-start)
+
+
+
+## Step 1: Create a table
+
+1. [Create a new table](/studio/concepts/tables#creating-a-table) named `SpendTable`.
+2. Add two columns to the table:
+ - **Cost** (set the type to **Number**)
+ - **ConversationID** (set the type to **String**)
+
+
+
+
+
+
+## Step 2: Add a Hook to track AI spend
+
+1. [Create a new Hook](/studio/concepts/hooks#add-a-hook) with the type [After Turn End](/studio/concepts/hooks#after-turn-end).
+2. Paste the following code into the Hook:
+
+```javascript
+// Convert spend from nano-dollars to dollars
+const llm_spend = metadata.tokens.cost / 1000000000
+
+// Create a row for the current turn's AI spend
+client.createTableRows({
+ table: 'SpendTable',
+ rows: [
+ {
+ Cost: llm_spend,
+ ConversationID: event.conversationId,
+ },
+ ],
+})
+```
+
+This Hook runs after each turn—that is, after the bot has received a message, processed it, and sent its response. The code snippet above does the following:
+
+- Retrieves the AI spend for the current turn
+- Convert the cost from nano-dollars into standard dollars
+- Saves the cost and conversation ID to the `SpendTable`
+
+## Step 3: Test your table
+
+Try chatting with your bot in the emulator. After every message your bot sends, your table should automatically create a new row. The AI spend will display in the **Cost** column:
+
+
+
+
+
+
+Your table will now keep a record of your bot's AI spend for each turn.
+
+## Step 4 (Optional): Calculate total AI spend per conversation
+
+Your table now stores the AI spend for each turn—but you can also store each conversation's total AI spend in a separate table.
+
+1. Create a second table named `TotalSpendTable`.
+2. Add the same two columns as the first table:
+ - **Cost** (set the type to **Number**)
+ - **ConversationID** (set the type to **String**)
+3. [Create a new Hook](/studio/concepts/hooks#add-a-hook) with the type [After Conversation End](/studio/concepts/hooks#after-conversation-end).
+4. Paste the following code into the Hook:
+
+```javascript
+// Finds table rows with the current conversation ID
+const tableResponse = await client.findTableRows({
+ table: 'SpendTable',
+ filter: {
+ ConversationID: event.conversationId,
+ },
+})
+
+// Calculates the total AI spend for the conversation
+let totalSpend = 0
+for (let i = 0; i < tableResponse.rows.length; i++) {
+ totalSpend += tableResponse.rows[i].Cost
+}
+
+// Creates a row in the new table with the total AI spend for the conversation
+client.createTableRows({
+ table: 'TotalSpendTable',
+ rows: [
+ {
+ Cost: totalSpend,
+ ConversationID: event.conversationId,
+ },
+ ],
+})
+```
+
+This Hook runs after the end of each conversation. The code snippet above does the following:
+
+- Retrieves the AI spend for each turn of the conversation
+- Sums them up to get the total AI spend for the conversation
+- Creates a row in `TotalSpendTable` with the total AI spend for the conversation
+
+
+
+ If you're using an Autonomous Node in your main [Workflow](/studio/concepts/workflows), the conversation will only end when it [times out](/studio/concepts/bot-settings#inactivity-timeout). This means you'll need to wait for the duration of your bot's inactivity timeout before your table updates with the total AI spend.
+
+
diff --git a/src/content/docs/studio/guides/how-to/translate.mdx b/src/content/docs/studio/guides/how-to/translate.mdx
new file mode 100644
index 0000000..291ca20
--- /dev/null
+++ b/src/content/docs/studio/guides/how-to/translate.mdx
@@ -0,0 +1,149 @@
+---
+title: Translate Webchat UI
+---
+
+import { Picture } from 'astro:assets'
+import deliveryStatusDarkImg from './assets/delivery-status-dark.png'
+import deliveryStatusImg from './assets/delivery-status.png'
+
+import { Tip, Check, Info } from '@/components/callouts'
+import Frame from '@/components/Frame.astro'
+
+If your bot is having conversations in a language other than English, you can translate its [Webchat](/webchat/) UI to match. This includes the bot's greeting, buttons, and any other text that appears in the Webchat window.
+
+
+ You will need:
+
+ - A [published bot](/get-started/quick-start)
+ - Knowledge of CSS
+
+ For the purposes of this guide, we'll translate the bot's Webchat UI to French. However, you can use the same steps to translate your bot's Webchat UI into any language.
+
+
+
+
+ Visual learner? Check out our [YouTube guide](https://www.youtube.com/watch?v=afZCpkWHZsI) on translating your bot.
+
+
+## Step 1: Translate elements from Webchat settings
+
+You can translate some elements of the Webchat UI directly from your bot's [Webchat settings](/webchat/get-started/configure-your-webchat):
+
+### Name and description
+
+To translate the name and description of your bot, modify the **Bot Name** and **Description** fields:
+
+
+
+### Composer placeholder
+
+To translate the placeholder text in the Composer, modify the **Composer placeholder** field:
+
+
+
+## Step 2: Translate elements with CSS
+
+Other elements of the Webchat UI need to be translated using CSS. To modify Webchat's built-in CSS classes:
+
+1. Open your bot's [Webchat settings](/webchat/get-started/configure-your-webchat).
+2. Go to **Bot Appearance**, then scroll to the **Styles** section.
+3. Copy and paste the CSS snippets below into the **Styles** section, then modify the highlighted lines as needed.
+
+
+ For a full list of Webchat CSS classes, check out our [guide on styling
+ Webchat](/webchat/get-started/configure-your-webchat#use-custom-styles).
+
+
+### New conversation modal
+
+You can translate the modal that appears when a user restarts a conversation:
+
+
+
+Just copy and paste the following CSS to the **Styles** section of your bot's Webchat settings, then modify the highlighted lines as needed:
+
+```css [expandable] {9, 24, 38}
+/* Change the modal's title */
+.bpModalTitle {
+ visibility: hidden;
+ position: relative;
+}
+.bpModalTitle:after {
+ visibility: visible;
+ position: absolute;
+ content: 'Créer une nouvelle conversation'; /* Replace this with your own translation*/
+}
+
+/* Change "New Conversation" */
+.bpModalButtonConfirm {
+ position: relative;
+ color: transparent;
+}
+.bpModalButtonConfirm:after {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: var(--message-text);
+ white-space: nowrap;
+ content: 'Nouvelle conversation'; /* Replace this with your own translation*/
+}
+
+.bpModalButtonCancel {
+ visibility: hidden;
+ position: relative;
+}
+
+.bpModalButtonCancel:after {
+ visibility: visible;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ content: 'Annuler'; /* Replace this with your own translation*/
+}
+```
+
+### "Today" label
+
+You can translate the "Today" label that appears in a Webchat conversation:
+
+
+
+Just copy and paste the following CSS to the **Styles** section of your bot's Webchat settings, then modify the highlighted lines as needed:
+
+```css [expandable] {8}
+/* Change the "Today" label text */
+div.bpMessageContainer[data-direction='system'] > p.bpMessageBlocksTextText {
+ visibility: hidden !important;
+ position: relative !important;
+}
+
+div.bpMessageContainer[data-direction='system'] > p.bpMessageBlocksTextText::before {
+ content: "Aujourd'hui" !important; /* Replace this with your own translation*/
+ visibility: visible !important;
+ position: absolute !important;
+ top: 0;
+ left: 0;
+ white-space: nowrap;
+}
+```
+
+Your bot's Webchat UI is now translated!
+
+### Delivery status
+
+You can change the "Delivered" label that appears after a user message is received:
+
+
+
+
+
+
+Just copy and paste the following CSS to the **Styles** section of your bot's Webchat settings, then modify the highlighted lines as needed:
+
+```css highlight={2}
+.bpReset .bpMessageDeliveryStatus::after {
+ content: 'Envoyé'; /* Replace this with your own translation*/
+}
+```
diff --git a/src/content/docs/studio/guides/introduction.mdx b/src/content/docs/studio/guides/introduction.mdx
new file mode 100644
index 0000000..9cce91a
--- /dev/null
+++ b/src/content/docs/studio/guides/introduction.mdx
@@ -0,0 +1,20 @@
+---
+title: Introduction
+---
+
+import { Tip } from '@/components/callouts'
+
+We believe the best way to learn Botpress is to **start using it**. Once you've finished the [Quickstart guide](/get-started/quick-start) and deployed your first bot, follow the how-to guides in this section and start building.
+
+
+Visual learner? You can find helpful video guides on the [Botpress YouTube channel](https://www.youtube.com/@Botpress). Whenever a page in this section has a corresponding video guide, we'll link to it.
+
+You can also check out the [Botpress Academy](https://botpress.com/academy) for crash courses on [pricing](https://botpress.com/academy-course/pricing), [navigating the UI](https://botpress.com/academy-course/ui-guide-studio), and more.
+
+
+
+## Learn by doing
+
+Botpress is a powerful, customizable platform—this means no one user will have exactly the same needs when building a bot.
+
+Our how-to guides are great for learning common use-cases and troubleshooting issues. However, **they might not walk you through every step of your own process**—and that's okay! We want to help you build confidence to experiment, so you can build bots that behave exactly how you want.
diff --git a/src/content/docs/studio/introduction.mdx b/src/content/docs/studio/introduction.mdx
new file mode 100644
index 0000000..03811f6
--- /dev/null
+++ b/src/content/docs/studio/introduction.mdx
@@ -0,0 +1,42 @@
+---
+title: Introduction to Studio
+sidebarTitle: Introduction
+description: >-
+ Development environment for building AI agents and chatbots.
+---
+
+import { Tip } from '@/components/callouts'
+import CardGroup from '@/components/CardGroup.astro'
+import Card from '@/components/Card.astro'
+
+{/* vale Vale.Spelling["Chatbot", "Chatbots", "chatbot", "chatbots"] = NO */}
+
+[Botpress Studio](https://studio.botpress.cloud) is an **integrated development environment (IDE)** for building, testing, and managing AI agents and chatbots. It combines advanced development tools with the simplicity of a **visual, drag-and-drop interface**, making it the central platform for all your bot development needs.
+
+
+ This section contains reference material for all concepts related to Botpress Studio. If you're looking for how-to
+ guides, check out the [Guides section](/studio/guides/introduction).
+
+
+## Key concepts
+
+
+
+ Sequences of steps your bot takes
+
+
+ Steps in a Workflow
+
+
+ Actions your bot can take within a Node
+
+
+ Sources your bot can refer to
+
+
+ Local databases for storing information
+
+
+ Containers for storing and reusing data
+
+