diff --git a/.vale.ini b/.vale.ini index 7e2bf298..53acfdd4 100644 --- a/.vale.ini +++ b/.vale.ini @@ -6,10 +6,13 @@ IgnoredScopes = code, tt, frontmatter BasedOnStyles = Vale, Botpress Markup = true -[for-developers/adk/*] +[/adk/*] Botpress.workflows = NO Vale.Terms = NO +[/desk/*] +Botpress.workflows = NO + [*] Botpress.button-capitalization = NO Botpress.chatbot = NO diff --git a/README.md b/README.md index e9523515..d4fa28a0 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,14 @@ To contribute, install the following software if you haven't already: ## Getting started 1. **Clone the repository:** + ```bash git clone https://github.com/botpress/docs.git cd docs ``` 2. **Install dependencies:** + ```bash pnpm install ``` @@ -41,10 +43,10 @@ The Botpress documentation is built with [Mintlify](https://mintlify.com/). Here docs/ ├── docs.json # Mintlify configuration & navigation ├── home.mdx # Homepage content -├── learn/ # Learning materials and guides +├── studio/ # Documentation for Botpress Studio ├── integrations/ # Integration documentation ├── webchat/ # Webchat-specific docs -├── for-developers/ # Developer-focused content +├── adk/ # Documentation for the Botpress Agent Development Kit (ADK) ├── api-reference/ # API documentation ├── snippets/ # Reusable content snippets ├── changelog.mdx # Product changelog @@ -56,10 +58,10 @@ docs/ ### MDX -All documentation is written in MDX (Markdown with JSX components). You can find full list of supported components in the [Mintlify documentation](https://mintlify.com/docs/text). +All documentation is written in MDX (Markdown with JSX components). You can find full list of supported components in the [Mintlify documentation](https://mintlify.com/docs/text). > [!NOTE] -> +> > If you're using VS Code or Cursor, we recommend also installing the official Mintlify extension. This will enable autocomplete for most Mintlify components. ### Images @@ -110,7 +112,7 @@ If you're working on documentation for an integration: ```zsh pnpm run update-integrations ``` - + This will fetch the most up-to-date information for any integrations modified on the current branch. > [!TIP] @@ -118,7 +120,7 @@ If you're working on documentation for an integration: > You can also update a single integration: > > ```zsh -> pnpm run update-integrations +> pnpm run update-integrations > ``` > > or update all integrations at once: @@ -139,7 +141,6 @@ This check also runs on every pull request in the repository. ## Development workflow - ### Make a change 1. Fork the repository @@ -149,7 +150,7 @@ This check also runs on every pull request in the repository. 5. Validate writing style with `make check-writing` (if Vale is installed) 6. Check for broken links using `mint broken-links` 7. Submit a pull request with a clear description of your changes - + ### Raise an issue Use this repository for specific documentation-related issues only. Report any product bugs (or general documentation feedback) via [Discord](https://discord.gg/botpress). @@ -158,4 +159,4 @@ Use this repository for specific documentation-related issues only. Report any p Join the conversation on our [Discord](https://discord.gg/botpress) server for any other questions related to Botpress—we'd love to hear from you. -Thank you for helping us improve the Botpress documentation! \ No newline at end of file +Thank you for helping us improve the Botpress documentation! diff --git a/for-developers/adk/cli-reference.mdx b/adk/cli-reference.mdx similarity index 100% rename from for-developers/adk/cli-reference.mdx rename to adk/cli-reference.mdx diff --git a/for-developers/adk/concepts/actions.mdx b/adk/concepts/actions.mdx similarity index 95% rename from for-developers/adk/concepts/actions.mdx rename to adk/concepts/actions.mdx index c2aa3a9a..a6860acb 100644 --- a/for-developers/adk/concepts/actions.mdx +++ b/adk/concepts/actions.mdx @@ -97,7 +97,7 @@ export default new Autonomous.Tool({ ### As a tool in a conversation -You can provide an action to your agent as a [tool](/for-developers/adk/concepts/tools) using the `asTool` method: +You can provide an action to your agent as a [tool](/adk/concepts/tools) using the `asTool` method: ```ts highlight={1,8} import { Conversation, actions } from "@botpress/runtime"; @@ -115,7 +115,7 @@ export default new Conversation({ ## Integration actions -When you [install an integration](/for-developers/adk/managing-integrations), its actions become available anywhere in your agent's source: +When you [install an integration](/adk/managing-integrations), its actions become available anywhere in your agent's source: ```ts highlight={1, 12-14} import { Trigger, actions } from "@botpress/runtime"; diff --git a/for-developers/adk/concepts/conversations.mdx b/adk/concepts/conversations.mdx similarity index 100% rename from for-developers/adk/concepts/conversations.mdx rename to adk/concepts/conversations.mdx diff --git a/for-developers/adk/concepts/knowledge.mdx b/adk/concepts/knowledge.mdx similarity index 100% rename from for-developers/adk/concepts/knowledge.mdx rename to adk/concepts/knowledge.mdx diff --git a/for-developers/adk/concepts/tables.mdx b/adk/concepts/tables.mdx similarity index 100% rename from for-developers/adk/concepts/tables.mdx rename to adk/concepts/tables.mdx diff --git a/for-developers/adk/concepts/tools.mdx b/adk/concepts/tools.mdx similarity index 97% rename from for-developers/adk/concepts/tools.mdx rename to adk/concepts/tools.mdx index 2c0719a1..d0ba53d0 100644 --- a/for-developers/adk/concepts/tools.mdx +++ b/adk/concepts/tools.mdx @@ -73,7 +73,7 @@ export default new Conversation({ ## Converting actions to tools -You can convert [actions](/for-developers/adk/concepts/actions) to tools using the `asTool()` method: +You can convert [actions](/adk/concepts/actions) to tools using the `asTool()` method: ```typescript highlight={1, 8} import { Conversation, actions } from "@botpress/runtime"; @@ -91,7 +91,7 @@ export default new Conversation({ ## Converting workflows to tools -You can convert [workflows](/for-developers/adk/concepts/workflows) to tools using the `asTool()` method: +You can convert [workflows](/adk/concepts/workflows) to tools using the `asTool()` method: ```typescript highlight={2, 9} import { Conversation } from "@botpress/runtime"; diff --git a/for-developers/adk/concepts/triggers.mdx b/adk/concepts/triggers.mdx similarity index 100% rename from for-developers/adk/concepts/triggers.mdx rename to adk/concepts/triggers.mdx diff --git a/for-developers/adk/concepts/workflows/overview.mdx b/adk/concepts/workflows/overview.mdx similarity index 95% rename from for-developers/adk/concepts/workflows/overview.mdx rename to adk/concepts/workflows/overview.mdx index 44fb7317..58f1cfee 100644 --- a/for-developers/adk/concepts/workflows/overview.mdx +++ b/adk/concepts/workflows/overview.mdx @@ -3,7 +3,7 @@ title: Workflows sidebarTitle: Overview --- -Workflows are long-running processes that handle complex, multi-step operations or scheduled tasks. Unlike [conversations](/for-developers/adk/concepts/conversations), workflows can run independently on a schedule or be triggered by events. +Workflows are long-running processes that handle complex, multi-step operations or scheduled tasks. Unlike [conversations](/adk/concepts/conversations), workflows can run independently on a schedule or be triggered by events. While workflows in the ADK are similar in concept to [Workflows](/studio/concepts/workflows) in Botpress Studio, they behave differently and shouldn't be treated as equivalent. @@ -78,13 +78,13 @@ Steps are *persisted*—if a workflow is interrupted, it can resume from the las The `step` object also provides many additional methods for workflow control: - + Learn about all available step methods ### Handling failing steps -If a step (or a [step method](/for-developers/adk/concepts/workflows/steps#methods)) fails, it'll throw a rejected promise. This will fail not only the current step, but the *entire workflow*. +If a step (or a [step method](/adk/concepts/workflows/steps#methods)) fails, it'll throw a rejected promise. This will fail not only the current step, but the *entire workflow*. To avoid this, make sure you catch errors gracefully: diff --git a/for-developers/adk/concepts/workflows/steps.mdx b/adk/concepts/workflows/steps.mdx similarity index 98% rename from for-developers/adk/concepts/workflows/steps.mdx rename to adk/concepts/workflows/steps.mdx index 86070b95..b56c7d95 100644 --- a/for-developers/adk/concepts/workflows/steps.mdx +++ b/adk/concepts/workflows/steps.mdx @@ -1,4 +1,4 @@ -This page contains a full reference for the [`step` function](/for-developers/adk/concepts/workflows/overview#steps). +This page contains a full reference for the [`step` function](/adk/concepts/workflows/overview#steps). ```typescript const data = await step("fetch-data", async () => { diff --git a/adk/introduction.mdx b/adk/introduction.mdx new file mode 100644 index 00000000..2f628159 --- /dev/null +++ b/adk/introduction.mdx @@ -0,0 +1,75 @@ + + + ```ts Basic agent + import { Conversation } from "@botpress/runtime"; + + export default new Conversation({ + channel: "*", + handler: async ({ execute, message }) => { + await execute({ + instructions: "You are a helpful assistant.", + }); + }, + }); + ``` + + ```ts Agent with knowledge + import { Conversation } from "@botpress/runtime"; + import { WebsiteKB } from "../knowledge/docs"; + + export default new Conversation({ + channel: "*", + handler: async ({ execute, message }) => { + await execute({ + instructions: "You are a helpful assistant.", + knowledge: [WebsiteKB] + }); + }, + }); + ``` + + + +The Agent Development Kit (ADK) is a **CLI tool and development framework for building AI agents** on Botpress. + +It provides a streamlined development experience with TypeScript support, hot reloading, and type-safe APIs for creating conversational AI applications. + +## Get started + + + + Build your first agent in minutes + + + Learn how an ADK project is organized + + + +## What is the ADK? + +The ADK is a framework that allows developers to build Botpress agents from code. It provides: + +- **Project scaffolding**: Quickly initialize new agent projects with templates +- **Type-safe development**: Automatic TypeScript type generation for integrations, interfaces, and more +- **Development workflow**: Hot reloading development server with live updates +- **Build and deploy**: Compile and deploy agents to Botpress Cloud +- **Integration management**: Add, update, and manage integrations from the Botpress Hub + +## When to use the ADK + +The ADK is ideal for: + +- Developers who prefer code-based workflows +- Teams using version control and CI/CD pipelines +- Projects requiring custom logic and integrations +- Developers who need TypeScript type safety + + +For most users, we recommend Botpress Studio. The ADK is best suited for developers who need more control or integration with development workflows. + diff --git a/for-developers/adk/managing-integrations.mdx b/adk/managing-integrations.mdx similarity index 100% rename from for-developers/adk/managing-integrations.mdx rename to adk/managing-integrations.mdx diff --git a/for-developers/adk/project-structure.mdx b/adk/project-structure.mdx similarity index 88% rename from for-developers/adk/project-structure.mdx rename to adk/project-structure.mdx index 18584012..07d03448 100644 --- a/for-developers/adk/project-structure.mdx +++ b/adk/project-structure.mdx @@ -1,24 +1,36 @@ -import { Files, File, Folder } from '/snippets/folder-component.jsx'; - ADK projects follow a consistent structure that organizes your agent's code, configuration, and dependencies. ## Directory structure - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## Configuration files @@ -352,10 +364,10 @@ Don't edit files in the `.botpress` directory manually. They are automatically g ## Next steps - + Learn about conversation handlers - + Create long-running processes diff --git a/for-developers/adk/getting-started.mdx b/adk/quickstart.mdx similarity index 95% rename from for-developers/adk/getting-started.mdx rename to adk/quickstart.mdx index 02ff658d..e1ead352 100644 --- a/for-developers/adk/getting-started.mdx +++ b/adk/quickstart.mdx @@ -127,7 +127,7 @@ Type "exit" or press ESC key to quit ### View the ADK console -Visit [`http://localhost:3001/`](http://localhost:3001/) to access the interactive ADK console. This gives you an intuitive, visual breakdown of your agent project and lets you [configure its integration's settings](/for-developers/adk/managing-integrations#integration-configuration). +Visit [`http://localhost:3001/`](http://localhost:3001/) to access the interactive ADK console. This gives you an intuitive, visual breakdown of your agent project and lets you [configure its integration's settings](/adk/managing-integrations#integration-configuration). ## Build your agent @@ -177,10 +177,10 @@ This uploads your agent to your Botpress workspace and makes it available for us ## Next steps - + Learn about ADK project organization - + Create your first conversation handler diff --git a/for-developers/zai/overview.mdx b/adk/zai/overview.mdx similarity index 77% rename from for-developers/zai/overview.mdx rename to adk/zai/overview.mdx index df29c289..da0c331f 100644 --- a/for-developers/zai/overview.mdx +++ b/adk/zai/overview.mdx @@ -9,11 +9,11 @@ Zai is an LLM utility library that provides a clean, type-safe API for common AI - Verify a Boolean condition within a piece of content - Generate or summarize text -We recommend using Zai with the [ADK](/for-developers/adk/overview) and [SDK](/for-developers/sdk/overview) to help process LLM inputs and outputs. +We recommend using Zai with the [ADK](/adk/introduction) and [SDK](/integrations/sdk/overview) to help process LLM inputs and outputs. - For a full list of available methods, check out the [reference section](/for-developers/zai/reference). + For a full list of available methods, check out the [reference section](/adk/zai/reference). @@ -78,7 +78,7 @@ Here are some examples of how you can use Zai: ### Get structured data from text -Use the [`extract`](/for-developers/zai/reference#extract) method to get structured data from a plain piece of text: +Use the [`extract`](/adk/zai/reference#extract) method to get structured data from a plain piece of text: ```ts const text = "Blueberries are 3.99$ and are in stock." @@ -94,7 +94,7 @@ const product = await zai.extract( ### Verify a condition -Use the [`check`](/for-developers/zai/reference#check) method to verify a condition against some input: +Use the [`check`](/adk/zai/reference#check) method to verify a condition against some input: ```ts const { output } = await zai.check(email, 'is spam').result() @@ -103,7 +103,7 @@ const { value, explanation } = output ### Filter an array -Use the [`filter`](/for-developers/zai/reference#filter) method to filter elements of an array based on a condition: +Use the [`filter`](/adk/zai/reference#filter) method to filter elements of an array based on a condition: ```ts const comments = [ @@ -117,7 +117,7 @@ const cleanComments = await zai.filter(comments, 'is not spam or inappropriate') ### Label content with categories -Use the [`label`](/for-developers/zai/reference#label) method to categorize content with predefined labels: +Use the [`label`](/adk/zai/reference#label) method to categorize content with predefined labels: ```ts const email = "Congratulations! You've won $1,000,000! Click here now!" @@ -131,7 +131,7 @@ const result = await zai.label(email, { ### Rewrite text according to instructions -Use the [`rewrite`](/for-developers/zai/reference#rewrite) method to transform text based on specific instructions: +Use the [`rewrite`](/adk/zai/reference#rewrite) method to transform text based on specific instructions: ```ts const original = "The meeting is scheduled for tomorrow at 3pm." @@ -144,7 +144,7 @@ const rewritten = await zai.rewrite( ### Summarize long content -Use the [`summarize`](/for-developers/zai/reference#summarize) method to create concise summaries of lengthy text: +Use the [`summarize`](/adk/zai/reference#summarize) method to create concise summaries of lengthy text: ```ts const longArticle = "..." // Long article content @@ -157,7 +157,7 @@ const summary = await zai.summarize(longArticle, { ### Generate text from prompts -Use the [`text`](/for-developers/zai/reference#text) method to generate content based on prompts: +Use the [`text`](/adk/zai/reference#text) method to generate content based on prompts: ```ts const blogPost = await zai.text( @@ -169,7 +169,7 @@ const blogPost = await zai.text( ### Sort items based on criteria -Use the [`sort`](/for-developers/zai/reference#sort) method to order items using natural language instructions: +Use the [`sort`](/adk/zai/reference#sort) method to order items using natural language instructions: ```ts const tasks = [ @@ -184,7 +184,7 @@ const prioritized = await zai.sort(tasks, 'by urgency and impact, most urgent fi ### Rate items on a scale -Use the [`rate`](/for-developers/zai/reference#rate) method to evaluate items on a 1-5 scale: +Use the [`rate`](/adk/zai/reference#rate) method to evaluate items on a 1-5 scale: ```ts const reviews = [ @@ -198,7 +198,7 @@ const ratings = await zai.rate(reviews, 'Rate the sentiment') ### Group items into categories -Use the [`group`](/for-developers/zai/reference#group) method to categorize items into groups: +Use the [`group`](/adk/zai/reference#group) method to categorize items into groups: ```ts const messages = [ @@ -215,7 +215,7 @@ const groups = await zai.group(messages, { ### Answer questions with citations -Use the [`answer`](/for-developers/zai/reference#answer) method to answer questions from documents with source citations: +Use the [`answer`](/adk/zai/reference#answer) method to answer questions from documents with source citations: ```ts const documents = [ @@ -232,7 +232,7 @@ if (result.type === 'answer') { ### Modify files with natural language -Use the [`patch`](/for-developers/zai/reference#patch) method to make surgical code edits across one or many files. Instead of regenerating entire files, it makes precise, minimal changes while preserving formatting and context: +Use the [`patch`](/adk/zai/reference#patch) method to make surgical code edits across one or many files. Instead of regenerating entire files, it makes precise, minimal changes while preserving formatting and context: ```ts const files = [{ diff --git a/for-developers/zai/reference.mdx b/adk/zai/reference.mdx similarity index 100% rename from for-developers/zai/reference.mdx rename to adk/zai/reference.mdx diff --git a/assistant.js b/assistant.js index 0e983c2e..fe8d93f5 100644 --- a/assistant.js +++ b/assistant.js @@ -1,478 +1,490 @@ // Bot panel -(function() { - 'use strict'; +;(function () { + 'use strict' if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initBotPanel); + document.addEventListener('DOMContentLoaded', initBotPanel) } else { - initBotPanel(); + initBotPanel() } function initBotPanel() { - const panel = document.createElement('div'); - panel.id = 'bot-panel'; - panel.classList.add('bot-panel', 'bot-panel-collapsed'); - - const toggleButton = document.createElement('button'); - toggleButton.id = 'bot-toggle'; - toggleButton.classList.add('bot-toggle'); - toggleButton.setAttribute('aria-label', 'Open bot'); + const panel = document.createElement('div') + panel.id = 'bot-panel' + panel.classList.add('bot-panel', 'bot-panel-collapsed') + + const toggleButton = document.createElement('button') + toggleButton.id = 'bot-toggle' + toggleButton.classList.add('bot-toggle') + toggleButton.setAttribute('aria-label', 'Open bot') toggleButton.innerHTML = ` - `; + ` - const toggleCloseButton = document.createElement('button'); - toggleCloseButton.id = 'bot-toggle-close'; - toggleCloseButton.classList.add('bot-toggle-close'); - toggleCloseButton.setAttribute('aria-label', 'Close bot'); + const toggleCloseButton = document.createElement('button') + toggleCloseButton.id = 'bot-toggle-close' + toggleCloseButton.classList.add('bot-toggle-close') + toggleCloseButton.setAttribute('aria-label', 'Close bot') toggleCloseButton.innerHTML = ` - `; + ` - const resizeHandle = document.createElement('div'); - resizeHandle.classList.add('bot-resize-handle'); - resizeHandle.setAttribute('aria-label', 'Resize panel'); + const resizeHandle = document.createElement('div') + resizeHandle.classList.add('bot-resize-handle') + resizeHandle.setAttribute('aria-label', 'Resize panel') - const mobileDismiss = document.createElement('div'); - mobileDismiss.classList.add('bot-mobile-dismiss'); - mobileDismiss.setAttribute('aria-label', 'Swipe down to close'); + const mobileDismiss = document.createElement('div') + mobileDismiss.classList.add('bot-mobile-dismiss') + mobileDismiss.setAttribute('aria-label', 'Swipe down to close') mobileDismiss.innerHTML = ` - `; - - const overlay = document.createElement('div'); - overlay.classList.add('bot-overlay'); - overlay.setAttribute('aria-label', 'Close panel'); - - const botContainer = document.createElement('div'); - botContainer.id = 'docs-bot'; - botContainer.classList.add('bot-iframe-container'); - - const iframe = document.createElement('iframe'); - iframe.title = 'Botpress'; - iframe.style.width = '100%'; - iframe.style.height = '100%'; - iframe.src = 'https://botpress.github.io/docs-bot/'; - - botContainer.appendChild(iframe); - - panel.appendChild(mobileDismiss); - resizeHandle.appendChild(toggleCloseButton); - panel.appendChild(botContainer); - panel.appendChild(resizeHandle); - - document.body.appendChild(overlay); - document.body.appendChild(panel); - document.body.appendChild(toggleButton); + ` + + const overlay = document.createElement('div') + overlay.classList.add('bot-overlay') + overlay.setAttribute('aria-label', 'Close panel') + + const botContainer = document.createElement('div') + botContainer.id = 'docs-bot' + botContainer.classList.add('bot-iframe-container') + + const iframe = document.createElement('iframe') + iframe.title = 'Botpress' + iframe.style.width = '100%' + iframe.style.height = '100%' + iframe.src = 'https://botpress.github.io/docs-bot/' + + botContainer.appendChild(iframe) + + panel.appendChild(mobileDismiss) + resizeHandle.appendChild(toggleCloseButton) + panel.appendChild(botContainer) + panel.appendChild(resizeHandle) + + document.body.appendChild(overlay) + document.body.appendChild(panel) + document.body.appendChild(toggleButton) function isMobile() { - return window.innerWidth <= 1024; + return window.innerWidth <= 1024 } function updateOverlay() { if (!isMobile()) { - overlay.classList.remove('visible'); - return; + overlay.classList.remove('visible') + return } - - const isExpanded = panel.classList.contains('bot-panel-expanded'); + + const isExpanded = panel.classList.contains('bot-panel-expanded') if (isExpanded) { - overlay.classList.add('visible'); + overlay.classList.add('visible') } else { - overlay.classList.remove('visible'); + overlay.classList.remove('visible') } } function focusComposerInput() { - const iframe = document.querySelector('iframe[title="Botpress"]'); + const iframe = document.querySelector('iframe[title="Botpress"]') if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'focusInput' - }, '*'); + iframe.contentWindow.postMessage( + { + type: 'focusInput', + }, + '*' + ) } } function sendPanelOpenedMessage() { - const iframe = document.querySelector('iframe[title="Botpress"]'); + const iframe = document.querySelector('iframe[title="Botpress"]') if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'panelOpened', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') - } - }, '*'); + iframe.contentWindow.postMessage( + { + type: 'panelOpened', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) } } - window.focusComposerInput = focusComposerInput; + window.focusComposerInput = focusComposerInput - window.askAi = function() { + window.askAi = function () { if (panel.classList.contains('bot-panel-collapsed')) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); - toggleButton.classList.add('bot-toggle-expanded'); - sendPanelOpenedMessage(); - focusComposerInput(); - updateOverlay(); + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') + toggleButton.classList.add('bot-toggle-expanded') + sendPanelOpenedMessage() + focusComposerInput() + updateOverlay() } - }; + } function togglePanel() { - const isCollapsed = panel.classList.contains('bot-panel-collapsed'); - + const isCollapsed = panel.classList.contains('bot-panel-collapsed') + if (isCollapsed) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); - toggleButton.classList.add('bot-toggle-expanded'); - sendPanelOpenedMessage(); - focusComposerInput(); + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') + toggleButton.classList.add('bot-toggle-expanded') + sendPanelOpenedMessage() + focusComposerInput() } else { - panel.classList.remove('bot-panel-expanded'); - panel.classList.add('bot-panel-collapsed'); - toggleButton.classList.remove('bot-toggle-expanded'); + panel.classList.remove('bot-panel-expanded') + panel.classList.add('bot-panel-collapsed') + toggleButton.classList.remove('bot-toggle-expanded') } - updateOverlay(); + updateOverlay() } function closePanel() { - panel.classList.remove('bot-panel-expanded'); - panel.classList.add('bot-panel-collapsed'); - panel.classList.remove('swiping'); - panel.style.transform = ''; - toggleButton.classList.remove('bot-toggle-expanded'); - updateOverlay(); + panel.classList.remove('bot-panel-expanded') + panel.classList.add('bot-panel-collapsed') + panel.classList.remove('swiping') + panel.style.transform = '' + toggleButton.classList.remove('bot-toggle-expanded') + updateOverlay() } - let isResizing = false; - let startX = 0; - let startWidth = 0; - let hasMoved = false; - const clickThreshold = 5; + let isResizing = false + let startX = 0 + let startWidth = 0 + let hasMoved = false + const clickThreshold = 5 resizeHandle.addEventListener('mousedown', (e) => { if (e.target.closest('#bot-toggle-close')) { - return; + return } - isResizing = true; - hasMoved = false; - startX = e.clientX; - startWidth = parseInt(window.getComputedStyle(panel).width, 10); - panel.classList.add('resizing'); - document.body.style.cursor = 'col-resize'; - document.body.style.userSelect = 'none'; - e.preventDefault(); - e.stopPropagation(); - }); + isResizing = true + hasMoved = false + startX = e.clientX + startWidth = parseInt(window.getComputedStyle(panel).width, 10) + panel.classList.add('resizing') + document.body.style.cursor = 'col-resize' + document.body.style.userSelect = 'none' + e.preventDefault() + e.stopPropagation() + }) document.addEventListener('mousemove', (e) => { - if (!isResizing) return; - - const moveDistance = Math.abs(e.clientX - startX); + if (!isResizing) return + + const moveDistance = Math.abs(e.clientX - startX) if (moveDistance > clickThreshold) { - hasMoved = true; + hasMoved = true } - + if (hasMoved) { - const diff = startX - e.clientX; - const maxWidth = window.innerWidth * 0.35; - const newWidth = Math.max(368, Math.min(maxWidth, startWidth + diff)); - panel.style.width = newWidth + 'px'; + const diff = startX - e.clientX + const maxWidth = window.innerWidth * 1 + const newWidth = Math.max(368, Math.min(maxWidth, startWidth + diff)) + panel.style.width = newWidth + 'px' } - - e.preventDefault(); - e.stopPropagation(); - }); + + e.preventDefault() + e.stopPropagation() + }) document.addEventListener('mouseup', (e) => { if (isResizing) { - isResizing = false; - panel.classList.remove('resizing'); - document.body.style.cursor = ''; - document.body.style.userSelect = ''; - + isResizing = false + panel.classList.remove('resizing') + document.body.style.cursor = '' + document.body.style.userSelect = '' + if (!hasMoved) { - togglePanel(); + togglePanel() } - - hasMoved = false; - e.preventDefault(); - e.stopPropagation(); + + hasMoved = false + e.preventDefault() + e.stopPropagation() } - }); + }) - let touchStartY = 0; - let touchCurrentY = 0; - let touchStartTime = 0; - let isSwiping = false; - const swipeThreshold = 100; - const swipeVelocityThreshold = 0.3; + let touchStartY = 0 + let touchCurrentY = 0 + let touchStartTime = 0 + let isSwiping = false + const swipeThreshold = 100 + const swipeVelocityThreshold = 0.3 function handleTouchStart(e) { - if (window.innerWidth > 1024) return; - if (!panel.classList.contains('bot-panel-expanded')) return; - - touchStartY = e.touches[0].clientY; - touchStartTime = Date.now(); - isSwiping = true; - panel.classList.add('swiping'); + if (window.innerWidth > 1024) return + if (!panel.classList.contains('bot-panel-expanded')) return + + touchStartY = e.touches[0].clientY + touchStartTime = Date.now() + isSwiping = true + panel.classList.add('swiping') } function handleTouchMove(e) { - if (!isSwiping || window.innerWidth > 1024) return; - if (!panel.classList.contains('bot-panel-expanded')) return; + if (!isSwiping || window.innerWidth > 1024) return + if (!panel.classList.contains('bot-panel-expanded')) return - touchCurrentY = e.touches[0].clientY; - const deltaY = touchCurrentY - touchStartY; + touchCurrentY = e.touches[0].clientY + const deltaY = touchCurrentY - touchStartY if (deltaY > 0) { - e.preventDefault(); - const translateY = Math.min(deltaY, window.innerHeight); - panel.style.transform = `translateX(0) translateY(${translateY}px)`; + e.preventDefault() + const translateY = Math.min(deltaY, window.innerHeight) + panel.style.transform = `translateX(0) translateY(${translateY}px)` } } function handleTouchEnd(e) { - if (!isSwiping || window.innerWidth > 1024) return; - if (!panel.classList.contains('bot-panel-expanded')) return; + if (!isSwiping || window.innerWidth > 1024) return + if (!panel.classList.contains('bot-panel-expanded')) return - const deltaY = touchCurrentY - touchStartY; - const timeDelta = Date.now() - touchStartTime; - const velocity = timeDelta > 0 ? deltaY / timeDelta : 0; + const deltaY = touchCurrentY - touchStartY + const timeDelta = Date.now() - touchStartTime + const velocity = timeDelta > 0 ? deltaY / timeDelta : 0 if (deltaY > swipeThreshold || velocity > swipeVelocityThreshold) { - closePanel(); + closePanel() } else { - panel.style.transform = ''; + panel.style.transform = '' } - panel.classList.remove('swiping'); - isSwiping = false; - touchStartY = 0; - touchCurrentY = 0; - touchStartTime = 0; + panel.classList.remove('swiping') + isSwiping = false + touchStartY = 0 + touchCurrentY = 0 + touchStartTime = 0 } - panel.addEventListener('touchstart', handleTouchStart, { passive: false }); - panel.addEventListener('touchmove', handleTouchMove, { passive: false }); - panel.addEventListener('touchend', handleTouchEnd, { passive: false }); - panel.addEventListener('touchcancel', handleTouchEnd, { passive: false }); + panel.addEventListener('touchstart', handleTouchStart, { passive: false }) + panel.addEventListener('touchmove', handleTouchMove, { passive: false }) + panel.addEventListener('touchend', handleTouchEnd, { passive: false }) + panel.addEventListener('touchcancel', handleTouchEnd, { passive: false }) - toggleButton.addEventListener('click', togglePanel); + toggleButton.addEventListener('click', togglePanel) toggleCloseButton.addEventListener('click', (e) => { - e.stopPropagation(); - closePanel(); - }); - mobileDismiss.addEventListener('click', closePanel); + e.stopPropagation() + closePanel() + }) + mobileDismiss.addEventListener('click', closePanel) overlay.addEventListener('click', (e) => { if (isMobile() && panel.classList.contains('bot-panel-expanded')) { - closePanel(); + closePanel() } - }); + }) function handleKeyboardShortcut(e) { - const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; - const modifierKey = isMac ? e.metaKey : e.ctrlKey; - + const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0 + const modifierKey = isMac ? e.metaKey : e.ctrlKey + if (e.key === 'Escape') { - const isExpanded = panel.classList.contains('bot-panel-expanded'); + const isExpanded = panel.classList.contains('bot-panel-expanded') if (isExpanded) { - e.preventDefault(); - closePanel(); + e.preventDefault() + closePanel() } } - + if (modifierKey && e.key === 'i' && !e.shiftKey && !e.altKey) { - e.preventDefault(); - const isCollapsed = panel.classList.contains('bot-panel-collapsed'); + e.preventDefault() + const isCollapsed = panel.classList.contains('bot-panel-collapsed') if (isCollapsed) { - togglePanel(); + togglePanel() } else { - closePanel(); + closePanel() } } } - document.addEventListener('keydown', handleKeyboardShortcut); + document.addEventListener('keydown', handleKeyboardShortcut) window.addEventListener('message', (event) => { if (event.data.type === 'togglePanel') { - const isCollapsed = panel.classList.contains('bot-panel-collapsed'); + const isCollapsed = panel.classList.contains('bot-panel-collapsed') if (isCollapsed) { - togglePanel(); + togglePanel() } else { - closePanel(); + closePanel() } } - + if (event.data.type === 'closePanel') { - closePanel(); + closePanel() } - + if (event.data.type === 'requestCurrentPage') { - sendPanelOpenedMessage(); + sendPanelOpenedMessage() } - }); + }) function handleHashChange() { if (window.location.hash === '#ask') { if (panel.classList.contains('bot-panel-collapsed')) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); - toggleButton.classList.add('bot-toggle-expanded'); - sendPanelOpenedMessage(); - focusComposerInput(); - updateOverlay(); + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') + toggleButton.classList.add('bot-toggle-expanded') + sendPanelOpenedMessage() + focusComposerInput() + updateOverlay() } } } - - handleHashChange(); - window.addEventListener('hashchange', handleHashChange); - updateOverlay(); - - let resizeTimeout; + + handleHashChange() + window.addEventListener('hashchange', handleHashChange) + updateOverlay() + + let resizeTimeout window.addEventListener('resize', () => { - clearTimeout(resizeTimeout); + clearTimeout(resizeTimeout) resizeTimeout = setTimeout(() => { - updateOverlay(); - const currentWidth = parseInt(window.getComputedStyle(panel).width, 10); - const maxWidth = window.innerWidth * 0.38; + updateOverlay() + const currentWidth = parseInt(window.getComputedStyle(panel).width, 10) + const maxWidth = window.innerWidth * 0.38 if (currentWidth > maxWidth) { - panel.style.width = maxWidth + 'px'; + panel.style.width = maxWidth + 'px' } - }, 100); - }); - + }, 100) + }) + const panelObserver = new MutationObserver(() => { - updateOverlay(); - }); - + updateOverlay() + }) + panelObserver.observe(panel, { attributes: true, - attributeFilter: ['class'] - }); - - let lastPath = window.location.pathname; + attributeFilter: ['class'], + }) + + let lastPath = window.location.pathname const checkPathChange = () => { if (window.location.pathname !== lastPath) { - lastPath = window.location.pathname; - - const isExpanded = panel.classList.contains('bot-panel-expanded'); + lastPath = window.location.pathname + + const isExpanded = panel.classList.contains('bot-panel-expanded') if (isExpanded) { - const iframe = document.querySelector('iframe[title="Botpress"]'); + const iframe = document.querySelector('iframe[title="Botpress"]') if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'pageChanged', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') - } - }, '*'); + iframe.contentWindow.postMessage( + { + type: 'pageChanged', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) } } } - }; - - setInterval(checkPathChange, 100); + } + + setInterval(checkPathChange, 100) window.addEventListener('popstate', () => { - setTimeout(checkPathChange, 10); - }); + setTimeout(checkPathChange, 10) + }) } -})(); +})() // Input bubble -(function() { - 'use strict'; +;(function () { + 'use strict' if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initInputBubble); + document.addEventListener('DOMContentLoaded', initInputBubble) } else { - initInputBubble(); + initInputBubble() } function initInputBubble() { - const inputBubble = document.createElement('div'); - inputBubble.id = 'ask-ai-input-bubble'; - inputBubble.classList.add('ask-ai-input-bubble'); - - const wrapper = document.createElement('div'); - wrapper.classList.add('ask-ai-input-wrapper'); - - const input = document.createElement('input'); - input.type = 'text'; - input.placeholder = 'Ask a question...'; - input.classList.add('ask-ai-input'); - input.setAttribute('aria-label', 'Ask a question...'); - - const shortcutIndicator = document.createElement('span'); - shortcutIndicator.classList.add('ask-ai-shortcut'); - const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; - shortcutIndicator.textContent = isMac ? '⌘I' : 'Ctrl+I'; - - const sendButton = document.createElement('button'); - sendButton.classList.add('ask-ai-send-button'); - sendButton.setAttribute('aria-label', 'Send message'); + const inputBubble = document.createElement('div') + inputBubble.id = 'ask-ai-input-bubble' + inputBubble.classList.add('ask-ai-input-bubble') + + const wrapper = document.createElement('div') + wrapper.classList.add('ask-ai-input-wrapper') + + const input = document.createElement('input') + input.type = 'text' + input.placeholder = 'Ask a question...' + input.classList.add('ask-ai-input') + input.setAttribute('aria-label', 'Ask a question...') + + const shortcutIndicator = document.createElement('span') + shortcutIndicator.classList.add('ask-ai-shortcut') + const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0 + shortcutIndicator.textContent = isMac ? '⌘I' : 'Ctrl+I' + + const sendButton = document.createElement('button') + sendButton.classList.add('ask-ai-send-button') + sendButton.setAttribute('aria-label', 'Send message') sendButton.innerHTML = ` - `; + ` - wrapper.appendChild(input); - wrapper.appendChild(shortcutIndicator); - wrapper.appendChild(sendButton); - inputBubble.appendChild(wrapper); - document.body.appendChild(inputBubble); + wrapper.appendChild(input) + wrapper.appendChild(shortcutIndicator) + wrapper.appendChild(sendButton) + inputBubble.appendChild(wrapper) + document.body.appendChild(inputBubble) - inputBubble.classList.add('ask-ai-input-bubble-hidden'); + inputBubble.classList.add('ask-ai-input-bubble-hidden') function isLandingPage() { - const path = window.location.pathname; - return path === '/' || path === '/docs' || path === '/index' || path.endsWith('/index.html'); + const path = window.location.pathname + return path === '/' || path === '/docs' || path === '/index' || path.endsWith('/index.html') } function isMobile() { - return window.innerWidth <= 1024; + return window.innerWidth <= 1024 } function handleEnterKey(e) { if (e.key === 'Enter' && !e.shiftKey && !isMobile()) { - e.preventDefault(); + e.preventDefault() if (input.value.trim()) { - handleAskAI(); + handleAskAI() } } } function handleMobileInputClick(e) { if (isMobile()) { - e.preventDefault(); - e.stopPropagation(); - const panel = document.getElementById('bot-panel'); - const toggleButton = document.getElementById('bot-toggle'); - + e.preventDefault() + e.stopPropagation() + const panel = document.getElementById('bot-panel') + const toggleButton = document.getElementById('bot-toggle') + if (panel && panel.classList.contains('bot-panel-collapsed')) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') if (toggleButton) { - toggleButton.classList.add('bot-toggle-expanded'); + toggleButton.classList.add('bot-toggle-expanded') } - const iframe = document.querySelector('iframe[title="Botpress"]'); + const iframe = document.querySelector('iframe[title="Botpress"]') if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'panelOpened', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') - } - }, '*'); + iframe.contentWindow.postMessage( + { + type: 'panelOpened', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) } if (window.focusComposerInput) { - window.focusComposerInput(); + window.focusComposerInput() } } } @@ -480,223 +492,242 @@ function setupInputBehavior() { if (isMobile()) { - input.readOnly = true; - input.removeEventListener('keydown', handleEnterKey); - input.addEventListener('click', handleMobileInputClick, { once: false }); - wrapper.addEventListener('click', handleMobileInputClick, { once: false }); + input.readOnly = true + input.removeEventListener('keydown', handleEnterKey) + input.addEventListener('click', handleMobileInputClick, { once: false }) + wrapper.addEventListener('click', handleMobileInputClick, { once: false }) } else { - input.readOnly = false; - input.removeEventListener('click', handleMobileInputClick); - wrapper.removeEventListener('click', handleMobileInputClick); - input.addEventListener('keydown', handleEnterKey); + input.readOnly = false + input.removeEventListener('click', handleMobileInputClick) + wrapper.removeEventListener('click', handleMobileInputClick) + input.addEventListener('keydown', handleEnterKey) } } - setupInputBehavior(); + setupInputBehavior() - let resizeTimeout; + let resizeTimeout window.addEventListener('resize', () => { - clearTimeout(resizeTimeout); + clearTimeout(resizeTimeout) resizeTimeout = setTimeout(() => { - setupInputBehavior(); - }, 100); - }); + setupInputBehavior() + }, 100) + }) function updateVisibility() { if (isLandingPage()) { - inputBubble.style.display = 'none'; - return; + inputBubble.style.display = 'none' + return } - const panel = document.getElementById('bot-panel'); + const panel = document.getElementById('bot-panel') if (panel) { - const isExpanded = panel.classList.contains('bot-panel-expanded'); + const isExpanded = panel.classList.contains('bot-panel-expanded') if (isExpanded) { - inputBubble.classList.add('ask-ai-input-bubble-hidden'); + inputBubble.classList.add('ask-ai-input-bubble-hidden') } else { - inputBubble.style.display = ''; + inputBubble.style.display = '' requestAnimationFrame(() => { requestAnimationFrame(() => { - inputBubble.classList.remove('ask-ai-input-bubble-hidden'); - }); - }); + inputBubble.classList.remove('ask-ai-input-bubble-hidden') + }) + }) } } else { - inputBubble.style.display = ''; + inputBubble.style.display = '' requestAnimationFrame(() => { requestAnimationFrame(() => { - inputBubble.classList.remove('ask-ai-input-bubble-hidden'); - }); - }); + inputBubble.classList.remove('ask-ai-input-bubble-hidden') + }) + }) } } - let lastPath = window.location.pathname; + let lastPath = window.location.pathname const checkPathChange = () => { if (window.location.pathname !== lastPath) { - lastPath = window.location.pathname; - updateVisibility(); + lastPath = window.location.pathname + updateVisibility() } - }; + } - setInterval(checkPathChange, 100); - window.addEventListener('popstate', updateVisibility); + setInterval(checkPathChange, 100) + window.addEventListener('popstate', updateVisibility) - const panel = document.getElementById('bot-panel'); + const panel = document.getElementById('bot-panel') if (panel) { const observer = new MutationObserver(() => { - updateVisibility(); - }); - + updateVisibility() + }) + observer.observe(panel, { attributes: true, - attributeFilter: ['class'] - }); - - updateVisibility(); + attributeFilter: ['class'], + }) + + updateVisibility() } else { const checkInterval = setInterval(() => { - const panel = document.getElementById('bot-panel'); + const panel = document.getElementById('bot-panel') if (panel) { const observer = new MutationObserver(() => { - updateVisibility(); - }); - + updateVisibility() + }) + observer.observe(panel, { attributes: true, - attributeFilter: ['class'] - }); - - updateVisibility(); - clearInterval(checkInterval); + attributeFilter: ['class'], + }) + + updateVisibility() + clearInterval(checkInterval) } - }, 100); + }, 100) } function updateSendButton() { - const hasValue = input.value.trim().length > 0; - sendButton.disabled = !hasValue; + const hasValue = input.value.trim().length > 0 + sendButton.disabled = !hasValue } - input.addEventListener('input', updateSendButton); - updateSendButton(); + input.addEventListener('input', updateSendButton) + updateSendButton() function handleAskAI() { - const message = input.value.trim(); - if (!message) return; + const message = input.value.trim() + if (!message) return + + const panel = document.getElementById('bot-panel') + const toggleButton = document.getElementById('bot-toggle') - const panel = document.getElementById('bot-panel'); - const toggleButton = document.getElementById('bot-toggle'); - if (panel && !panel.classList.contains('bot-panel-expanded')) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') if (toggleButton) { - toggleButton.classList.add('bot-toggle-expanded'); + toggleButton.classList.add('bot-toggle-expanded') } } - const iframe = document.querySelector('iframe[title="Botpress"]'); + const iframe = document.querySelector('iframe[title="Botpress"]') if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'panelOpened', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') - } - }, '*'); - - iframe.contentWindow.postMessage({ - type: 'sendMessage', - message: message - }, '*'); + iframe.contentWindow.postMessage( + { + type: 'panelOpened', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) + + iframe.contentWindow.postMessage( + { + type: 'sendMessage', + message: message, + }, + '*' + ) } - input.value = ''; - updateSendButton(); - input.blur(); + input.value = '' + updateSendButton() + input.blur() } sendButton.addEventListener('click', (e) => { - e.preventDefault(); + e.preventDefault() if (!sendButton.disabled) { - handleAskAI(); + handleAskAI() } - }); + }) } -})(); +})() // "Ask AI" button override -(function() { - 'use strict'; +;(function () { + 'use strict' if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initAskAIOverride); + document.addEventListener('DOMContentLoaded', initAskAIOverride) } else { - initAskAIOverride(); + initAskAIOverride() } function initAskAIOverride() { - const overriddenButtons = new WeakSet(); - + const overriddenButtons = new WeakSet() + function findAndOverrideButton() { - const button = document.getElementById('page-context-menu-button'); - + const button = document.getElementById('page-context-menu-button') + if (button && button.innerText.trim() === 'Ask AI' && !overriddenButtons.has(button)) { - button.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - - const panel = document.getElementById('bot-panel'); - const toggleButton = document.getElementById('bot-toggle'); - - if (panel && !panel.classList.contains('bot-panel-expanded')) { - panel.classList.remove('bot-panel-collapsed'); - panel.classList.add('bot-panel-expanded'); - if (toggleButton) { - toggleButton.classList.add('bot-toggle-expanded'); - } - } - - const iframe = document.querySelector('iframe[title="Botpress"]'); - if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage({ - type: 'panelOpened', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') + button.addEventListener( + 'click', + (e) => { + e.preventDefault() + e.stopPropagation() + + const panel = document.getElementById('bot-panel') + const toggleButton = document.getElementById('bot-toggle') + + if (panel && !panel.classList.contains('bot-panel-expanded')) { + panel.classList.remove('bot-panel-collapsed') + panel.classList.add('bot-panel-expanded') + if (toggleButton) { + toggleButton.classList.add('bot-toggle-expanded') } - }, '*'); - - iframe.contentWindow.postMessage({ - type: 'askAI', - data: { - path: window.location.pathname, - title: document.title.replace(' - Botpress', '') - } - }, '*'); - - iframe.contentWindow.postMessage({ - type: 'focusInput' - }, '*'); - } - }, true); - - overriddenButtons.add(button); - return true; + } + + const iframe = document.querySelector('iframe[title="Botpress"]') + if (iframe && iframe.contentWindow) { + iframe.contentWindow.postMessage( + { + type: 'panelOpened', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) + + iframe.contentWindow.postMessage( + { + type: 'askAI', + data: { + path: window.location.pathname, + title: document.title.replace(' - Botpress', ''), + }, + }, + '*' + ) + + iframe.contentWindow.postMessage( + { + type: 'focusInput', + }, + '*' + ) + } + }, + true + ) + + overriddenButtons.add(button) + return true } - return false; + return false } - findAndOverrideButton(); + findAndOverrideButton() const observer = new MutationObserver(() => { - findAndOverrideButton(); - }); + findAndOverrideButton() + }) observer.observe(document.body, { childList: true, - subtree: true - }); + subtree: true, + }) } -})(); \ No newline at end of file +})() diff --git a/desk/introduction.mdx b/desk/introduction.mdx new file mode 100644 index 00000000..82d4decd --- /dev/null +++ b/desk/introduction.mdx @@ -0,0 +1,24 @@ +Desk is a **customer experience workspace for human-AI teams**. It combines a familiar interface with powerful AI-assisted tools, like: + +- Suggested answers to customer messages +- Two-way translation +- Copilot that refers to your knowledge bases +- AI insights and knowledge gap reports + + + Desk is currently available upon request for Team, Managed, and Enterprise customers. + + +## What makes Desk different? + +Desk is a support workspace built for how real support teams operate: fast triage, clear context, and human oversight that stays part of the workflow. AI helps where it's reliable, and routes to an agent when judgment matters. + +## Integrations + +Desk is designed for gradual adoption. We'll help you import your existing customers and data from your existing support solution, like Intercom or Zendesk. + +Then, all your customer interactions sync when you take actions on either platform, so there's no risk. diff --git a/docs.json b/docs.json index c10ad5d7..3d8f0798 100644 --- a/docs.json +++ b/docs.json @@ -67,7 +67,6 @@ "pages": [ { "group": "Get started", - "icon": "rocket", "pages": [ "/index", "/get-started/quick-start", @@ -86,11 +85,41 @@ "/get-started/configure-your-workspace" ] }, + { + "group": "ADK", + "tag": "Beta", + "pages": [ + "/adk/introduction", + "/adk/quickstart", + "/adk/project-structure", + { + "group": "Concepts", + "pages": [ + "/adk/concepts/conversations", + { + "group": "Workflows", + "pages": ["/adk/concepts/workflows/overview", "/adk/concepts/workflows/steps"] + }, + "/adk/concepts/actions", + "/adk/concepts/tables", + "/adk/concepts/triggers", + "/adk/concepts/knowledge", + "/adk/concepts/tools" + ] + }, + "/adk/managing-integrations", + { + "group": "Zai", + "pages": ["/adk/zai/overview", "/adk/zai/reference"] + }, + "/adk/cli-reference" + ] + }, { "group": "Studio", - "icon": "share-2", "pages": [ "/studio/introduction", + "/tutorial", { "group": "Concepts", "pages": [ @@ -246,7 +275,6 @@ }, { "group": "Integrations", - "icon": "boxes", "pages": [ "/integrations/get-started/introduction", "/integrations/get-started/botpress-hub", @@ -260,6 +288,7 @@ "/integrations/integration-guides/bamboohr", "/integrations/integration-guides/canny", "/integrations/integration-guides/chat", + "/integrations/functional-integrations/conversation-analyzer", "/integrations/integration-guides/chatwoot", "/integrations/integration-guides/plus-email-notifier", "/integrations/integration-guides/github", @@ -270,9 +299,11 @@ "/integrations/integration-guides/hitl", "/integrations/integration-guides/hubspot", "/integrations/integration-guides/hunter", + "/integrations/functional-integrations/improvement", "/integrations/integration-guides/instagram", "/integrations/integration-guides/intercom", "integrations/integration-guides/klaviyo", + "/integrations/functional-integrations/knowledge-base-optimization", "/integrations/integration-guides/line", "/integrations/integration-guides/loops", "/integrations/integration-guides/mailerlite", @@ -318,19 +349,38 @@ ] }, { - "group": "Functional integrations", + "group": "SDK", "pages": [ - "/integrations/functional-integrations/introduction", - "/integrations/functional-integrations/knowledge-base-optimization", - "/integrations/functional-integrations/conversation-analyzer", - "/integrations/functional-integrations/improvement" + "integrations/sdk/overview", + "integrations/sdk/installation", + { + "group": "Integrations", + "pages": [ + "integrations/sdk/integration/getting-started", + "integrations/sdk/integration/messaging", + "integrations/sdk/integration/concepts", + "integrations/sdk/integration/publish-your-integration-on-botpress-hub", + "integrations/sdk/integration/enable-oauth", + "integrations/sdk/integration/use-your-own-llm" + ] + }, + { + "group": "Interfaces", + "pages": [ + "integrations/sdk/interface/introduction", + "integrations/sdk/interface/how-tos/add-and-implement", + "integrations/sdk/interface/how-tos/implementing-hitl", + "integrations/sdk/interface/how-tos/implementing-file-sync" + ] + }, + "integrations/sdk/bots-as-code", + "/integrations/sdk/cli-reference" ] } ] }, { "group": "Webchat", - "icon": "message-square", "pages": [ "/webchat/get-started/introduction", "/webchat/get-started/quick-start", @@ -393,73 +443,8 @@ ] }, { - "group": "For developers", - "icon": "hammer", - "pages": [ - "for-developers/introduction", - { - "group": "ADK", - "tag": "BETA", - "pages": [ - "for-developers/adk/overview", - "for-developers/adk/getting-started", - "for-developers/adk/project-structure", - { - "group": "Concepts", - "pages": [ - "for-developers/adk/concepts/conversations", - { - "group": "Workflows", - "pages": [ - "for-developers/adk/concepts/workflows/overview", - "for-developers/adk/concepts/workflows/steps" - ] - }, - "for-developers/adk/concepts/actions", - "for-developers/adk/concepts/tables", - "for-developers/adk/concepts/triggers", - "for-developers/adk/concepts/knowledge", - "for-developers/adk/concepts/tools" - ] - }, - "for-developers/adk/managing-integrations", - "for-developers/adk/cli-reference" - ] - }, - { - "group": "SDK", - "pages": [ - "for-developers/sdk/overview", - "for-developers/sdk/installation", - { - "group": "Integrations", - "pages": [ - "for-developers/sdk/integration/getting-started", - "for-developers/sdk/integration/messaging", - "for-developers/sdk/integration/concepts", - "for-developers/sdk/integration/publish-your-integration-on-botpress-hub", - "for-developers/sdk/integration/enable-oauth", - "for-developers/sdk/integration/use-your-own-llm" - ] - }, - { - "group": "Interfaces", - "pages": [ - "for-developers/sdk/interface/introduction", - "for-developers/sdk/interface/how-tos/add-and-implement", - "for-developers/sdk/interface/how-tos/implementing-hitl", - "for-developers/sdk/interface/how-tos/implementing-file-sync" - ] - }, - "for-developers/sdk/bots-as-code", - "/for-developers/sdk/cli-reference" - ] - }, - { - "group": "Zai", - "pages": ["for-developers/zai/overview", "for-developers/zai/reference"] - } - ] + "group": "Desk", + "pages": ["desk/introduction"] } ] }, @@ -647,6 +632,18 @@ { "source": "/learn/guides/:slug*", "destination": "/studio/guides/:slug*" + }, + { + "source": "/for-developers/adk/:slug*", + "destination": "/adk/:slug*" + }, + { + "source": "/for-developers/zai/:slug*", + "destination": "/adk/zai/:slug*" + }, + { + "source": "/for-developers/sdk/:slug*", + "destination": "/integrations/sdk/:slug*" } ], "integrations": { diff --git a/for-developers/adk/overview.mdx b/for-developers/adk/overview.mdx deleted file mode 100644 index 49382cc2..00000000 --- a/for-developers/adk/overview.mdx +++ /dev/null @@ -1,40 +0,0 @@ -The **Agent Development Kit (ADK)** is a CLI tool and development framework for building AI agents on Botpress. It provides a streamlined development experience with TypeScript support, hot reloading, and type-safe APIs for creating conversational AI applications. - - - The [Botpress documentation assistant](#ask) is built entirely using the ADK and the [Webchat React library](/webchat/react-library/get-started). You can [check out the source code on GitHub](https://github.com/botpress/docs-bot). - - -## What is the ADK? - -The ADK allows developers to build Botpress agents using code instead of the Studio interface. It provides: - -- **Project scaffolding**: Quickly initialize new agent projects with templates -- **Type-safe development**: Automatic TypeScript type generation for integrations, interfaces, and more -- **Development workflow**: Hot reloading development server with live updates -- **Build and deploy**: Compile and deploy agents to Botpress Cloud -- **Integration management**: Add, update, and manage integrations from the Botpress Hub - -## When to use the ADK - -The ADK is ideal for: - -- Developers who prefer code-based workflows -- Teams using version control and CI/CD pipelines -- Projects requiring custom logic and integrations -- Developers who need TypeScript type safety - - -For most users, we recommend Botpress Studio. The ADK is best suited for developers who need more control or integration with development workflows. - - -## Next steps - - - - Set up your first ADK project - - - Learn about ADK project organization - - - diff --git a/for-developers/introduction.mdx b/for-developers/introduction.mdx deleted file mode 100644 index 84ef48da..00000000 --- a/for-developers/introduction.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Botpress for developers -sidebarTitle: Introduction ---- - -Botpress offers a variety of **developer tools and packages** to build, analyze and manage your agents. - - - Botpress also offers a [React library for Webchat](/webchat/react-library/get-started) and [several APIs](/api-reference/introduction) you can use to interact with the platform. - - -## Get started - - - - Develop an AI agent from code - - BETA - - - Build your own integration and publish on Botpress Hub - - - Perform type-safe AI operations - - diff --git a/get-started/configure-your-workspace.mdx b/get-started/configure-your-workspace.mdx index fc88ad06..9482afdb 100644 --- a/get-started/configure-your-workspace.mdx +++ b/get-started/configure-your-workspace.mdx @@ -90,7 +90,7 @@ If you just want to install third-party integrations, you can ignore this menu To learn more about building and deploying your own integrations: - + Software development kit for building and deploying integrations on Botpress. diff --git a/home-components/IntegrationsCard.jsx b/home-components/IntegrationsCard.jsx new file mode 100644 index 00000000..80f67556 --- /dev/null +++ b/home-components/IntegrationsCard.jsx @@ -0,0 +1,53 @@ +export const IntegrationsCard = () => ( + +
+
+ + + + + + +
+
+

+ Integrations + + + +

+
+ Channels to deploy or interact with your agent. +
+
+
+
+) diff --git a/home-components/WebchatCard.jsx b/home-components/WebchatCard.jsx new file mode 100644 index 00000000..e5c75e7f --- /dev/null +++ b/home-components/WebchatCard.jsx @@ -0,0 +1,50 @@ +export const WebchatCard = () => ( + +
+
+ + + +
+
+

+ Webchat + + + +

+
+ Custom frontend for your AI agent. +
+
+
+
+) diff --git a/homepage-assets/adk.jpg b/homepage-assets/adk.jpg new file mode 100644 index 00000000..bdee4950 Binary files /dev/null and b/homepage-assets/adk.jpg differ diff --git a/homepage-assets/desk.jpg b/homepage-assets/desk.jpg new file mode 100644 index 00000000..52257aa4 Binary files /dev/null and b/homepage-assets/desk.jpg differ diff --git a/homepage-assets/studio.jpg b/homepage-assets/studio.jpg new file mode 100644 index 00000000..931f4384 Binary files /dev/null and b/homepage-assets/studio.jpg differ diff --git a/index.mdx b/index.mdx index d81738c2..bae6847c 100644 --- a/index.mdx +++ b/index.mdx @@ -1,187 +1,78 @@ --- title: 'Welcome to Botpress' -mode: 'frame' +mode: frame --- -
-
- Banner +import { WebchatCard } from '/home-components/WebchatCard.jsx' +import { IntegrationsCard } from '/home-components/IntegrationsCard.jsx' - Banner -
-
-

- Documentation -

+
+
+

+ Documentation +

-
- Learn how to use Botpress, the complete AI agent platform. -
-
- - -
Get help
-
+
+ Learn how to use Botpress, the complete AI agent platform.
+
+ + +
Get help
+
+
- -
+
-

- Build -

- - - - Build and deploy your first AI agent - - - - Learn the key concepts of Botpress - - - - Follow detailed how-to guides - - + + TypeScript library for building AI agents from code Beta +
-

- Deploy -

- - - - Embed a bot on your website - - - - Connect a bot to external services - - - - Build a bot into your React project - - + + Visual, drag-and-drop interface for building AI agents +
-

- For developers -

- - - - Build a powerful AI agent from code BETA - - - - Build and publish your own integration - - - - Interact with Botpress using our APIs - - + + Customer support workspace for human-AI teams +
-
-

- Browse by concept -

- -
-
- Conversational logic -
- - - - Sequences of steps a bot takes - - - - Steps in a Workflow - - - - Actions a bot can take within a Node - - - - Nodes that trigger for certain events - - - - Sources a bot can refer to - - - - Helpers that extend a bot's capabilities - - - -
- Data manipulation -
- - - - Local databases for storing information - - - - Containers for storing and reusing data - - - - Blueprints for data your bot uses - - - -
- Custom code -
- - - - Code snippets for AI - - - - Code snippets for a bot's lifecycle - - - -
- Maintenance -
- - - - History of changes to your bot - - - - Playground to test and debug your bot - - - - Tools to inspect your bot's behaviour - - +
+
+ +
+
+
diff --git a/integrations/get-started/assets/explore-hub.png b/integrations/get-started/assets/explore-hub.png deleted file mode 100644 index d352a96f..00000000 Binary files a/integrations/get-started/assets/explore-hub.png and /dev/null differ diff --git a/integrations/get-started/botpress-hub.mdx b/integrations/get-started/botpress-hub.mdx index e9e88f26..ea0ff17f 100644 --- a/integrations/get-started/botpress-hub.mdx +++ b/integrations/get-started/botpress-hub.mdx @@ -12,17 +12,12 @@ Botpress Hub is a **marketplace for integrations**. You can browse the Hub to fi - Want to build your own integration and publish it on Botpress Hub? Check out the [For Developers](/for-developers/sdk/overview) section. + Want to build your own integration and publish it on Botpress Hub? Check out the [For Developers](/integrations/sdk/overview) section. ## Access Botpress Hub -

- To access Botpress Hub, select - Explore Hub - in the upper-right corner of the [Studio](/studio/introduction). -

- +To access Botpress Hub, select **Explore Hub** in the upper-right corner of the [Studio](/studio/introduction). ## Install an integration Use the search bar or filters to find an integration: diff --git a/integrations/get-started/introduction.mdx b/integrations/get-started/introduction.mdx index 62dfb7ad..0d1e785f 100644 --- a/integrations/get-started/introduction.mdx +++ b/integrations/get-started/introduction.mdx @@ -10,7 +10,7 @@ You can use our pre-built [functional integrations](/integrations/functional-int - Want to build your own integration and publish it on [Botpress Hub](/integrations/get-started/botpress-hub)? Check out the [For Developers](/for-developers/sdk/integration/getting-started) section. + Want to build your own integration and publish it on [Botpress Hub](/integrations/get-started/botpress-hub)? Check out the [For Developers](/integrations/sdk/integration/getting-started) section. diff --git a/for-developers/sdk/bots-as-code.mdx b/integrations/sdk/bots-as-code.mdx similarity index 100% rename from for-developers/sdk/bots-as-code.mdx rename to integrations/sdk/bots-as-code.mdx diff --git a/for-developers/sdk/cli-reference.mdx b/integrations/sdk/cli-reference.mdx similarity index 100% rename from for-developers/sdk/cli-reference.mdx rename to integrations/sdk/cli-reference.mdx diff --git a/for-developers/sdk/installation.mdx b/integrations/sdk/installation.mdx similarity index 100% rename from for-developers/sdk/installation.mdx rename to integrations/sdk/installation.mdx diff --git a/for-developers/sdk/integration/assets/config-github-1-dark.png b/integrations/sdk/integration/assets/config-github-1-dark.png similarity index 100% rename from for-developers/sdk/integration/assets/config-github-1-dark.png rename to integrations/sdk/integration/assets/config-github-1-dark.png diff --git a/for-developers/sdk/integration/assets/config-github-1.png b/integrations/sdk/integration/assets/config-github-1.png similarity index 100% rename from for-developers/sdk/integration/assets/config-github-1.png rename to integrations/sdk/integration/assets/config-github-1.png diff --git a/for-developers/sdk/integration/assets/config-github-2-dark.png b/integrations/sdk/integration/assets/config-github-2-dark.png similarity index 100% rename from for-developers/sdk/integration/assets/config-github-2-dark.png rename to integrations/sdk/integration/assets/config-github-2-dark.png diff --git a/for-developers/sdk/integration/assets/config-github-2.png b/integrations/sdk/integration/assets/config-github-2.png similarity index 100% rename from for-developers/sdk/integration/assets/config-github-2.png rename to integrations/sdk/integration/assets/config-github-2.png diff --git a/for-developers/sdk/integration/assets/config-linear-dark.png b/integrations/sdk/integration/assets/config-linear-dark.png similarity index 100% rename from for-developers/sdk/integration/assets/config-linear-dark.png rename to integrations/sdk/integration/assets/config-linear-dark.png diff --git a/for-developers/sdk/integration/assets/config-linear.png b/integrations/sdk/integration/assets/config-linear.png similarity index 100% rename from for-developers/sdk/integration/assets/config-linear.png rename to integrations/sdk/integration/assets/config-linear.png diff --git a/for-developers/sdk/integration/botpress-profile.png b/integrations/sdk/integration/botpress-profile.png similarity index 100% rename from for-developers/sdk/integration/botpress-profile.png rename to integrations/sdk/integration/botpress-profile.png diff --git a/for-developers/sdk/integration/concepts.mdx b/integrations/sdk/integration/concepts.mdx similarity index 100% rename from for-developers/sdk/integration/concepts.mdx rename to integrations/sdk/integration/concepts.mdx diff --git a/for-developers/sdk/integration/enable-oauth.mdx b/integrations/sdk/integration/enable-oauth.mdx similarity index 100% rename from for-developers/sdk/integration/enable-oauth.mdx rename to integrations/sdk/integration/enable-oauth.mdx diff --git a/for-developers/sdk/integration/getting-started.mdx b/integrations/sdk/integration/getting-started.mdx similarity index 100% rename from for-developers/sdk/integration/getting-started.mdx rename to integrations/sdk/integration/getting-started.mdx diff --git a/for-developers/sdk/integration/make-public.png b/integrations/sdk/integration/make-public.png similarity index 100% rename from for-developers/sdk/integration/make-public.png rename to integrations/sdk/integration/make-public.png diff --git a/for-developers/sdk/integration/messaging.mdx b/integrations/sdk/integration/messaging.mdx similarity index 100% rename from for-developers/sdk/integration/messaging.mdx rename to integrations/sdk/integration/messaging.mdx diff --git a/for-developers/sdk/integration/publish-your-integration-on-botpress-hub.mdx b/integrations/sdk/integration/publish-your-integration-on-botpress-hub.mdx similarity index 100% rename from for-developers/sdk/integration/publish-your-integration-on-botpress-hub.mdx rename to integrations/sdk/integration/publish-your-integration-on-botpress-hub.mdx diff --git a/for-developers/sdk/integration/request-verification.png b/integrations/sdk/integration/request-verification.png similarity index 100% rename from for-developers/sdk/integration/request-verification.png rename to integrations/sdk/integration/request-verification.png diff --git a/for-developers/sdk/integration/use-your-own-llm.mdx b/integrations/sdk/integration/use-your-own-llm.mdx similarity index 100% rename from for-developers/sdk/integration/use-your-own-llm.mdx rename to integrations/sdk/integration/use-your-own-llm.mdx diff --git a/for-developers/sdk/interface/concepts/entities.mdx b/integrations/sdk/interface/concepts/entities.mdx similarity index 100% rename from for-developers/sdk/interface/concepts/entities.mdx rename to integrations/sdk/interface/concepts/entities.mdx diff --git a/for-developers/sdk/interface/how-tos/add-and-implement.mdx b/integrations/sdk/interface/how-tos/add-and-implement.mdx similarity index 96% rename from for-developers/sdk/interface/how-tos/add-and-implement.mdx rename to integrations/sdk/interface/how-tos/add-and-implement.mdx index 52117f3f..568339f8 100644 --- a/for-developers/sdk/interface/how-tos/add-and-implement.mdx +++ b/integrations/sdk/interface/how-tos/add-and-implement.mdx @@ -62,7 +62,7 @@ Once you have the interface name and version, you can add it as a dependency to Save the `package.json` file. - Now that you have added the interface as a dependency, you can run the [`bp add`](/for-developers/sdk/cli-reference#add) command to install it. This command will: + Now that you have added the interface as a dependency, you can run the [`bp add`](/integrations/sdk/cli-reference#add) command to install it. This command will: - Download the interface from Botpress. - Install it in a directory named `bp_modules` in your integration's root directory. @@ -130,7 +130,7 @@ Since each interface has its own specific requirements, you should refer to the icon={} horizontal title="Human in the loop" - href="/for-developers/sdk/interface/how-tos/implementing-hitl" + href="/integrations/sdk/interface/how-tos/implementing-hitl" > How to implement Human in the loop diff --git a/for-developers/sdk/interface/how-tos/implementing-file-sync.mdx b/integrations/sdk/interface/how-tos/implementing-file-sync.mdx similarity index 99% rename from for-developers/sdk/interface/how-tos/implementing-file-sync.mdx rename to integrations/sdk/interface/how-tos/implementing-file-sync.mdx index 60961d08..a5767f4d 100644 --- a/for-developers/sdk/interface/how-tos/implementing-file-sync.mdx +++ b/integrations/sdk/interface/how-tos/implementing-file-sync.mdx @@ -109,7 +109,7 @@ Once you have the version, you can ad Save the `package.json` file. - Now that you have added the as a dependency, you can run the [`bp add`](/for-developers/sdk/cli-reference#add) command to install it. This command will: + Now that you have added the as a dependency, you can run the [`bp add`](/integrations/sdk/cli-reference#add) command to install it. This command will: - Download the interface from Botpress. - Install it in a directory named `bp_modules` in your 's root directory. diff --git a/for-developers/sdk/interface/how-tos/implementing-hitl.mdx b/integrations/sdk/interface/how-tos/implementing-hitl.mdx similarity index 99% rename from for-developers/sdk/interface/how-tos/implementing-hitl.mdx rename to integrations/sdk/interface/how-tos/implementing-hitl.mdx index fe6056bc..fd2e4f7a 100644 --- a/for-developers/sdk/interface/how-tos/implementing-hitl.mdx +++ b/integrations/sdk/interface/how-tos/implementing-hitl.mdx @@ -108,7 +108,7 @@ Once you have the version, you can ad Save the `package.json` file. - Now that you have added the as a dependency, you can run the [`bp add`](/for-developers/sdk/cli-reference#add) command to install it. This command will: + Now that you have added the as a dependency, you can run the [`bp add`](/integrations/sdk/cli-reference#add) command to install it. This command will: - Download the interface from Botpress. - Install it in a directory named `bp_modules` in your 's root directory. diff --git a/for-developers/sdk/interface/introduction.mdx b/integrations/sdk/interface/introduction.mdx similarity index 100% rename from for-developers/sdk/interface/introduction.mdx rename to integrations/sdk/interface/introduction.mdx diff --git a/for-developers/sdk/overview.mdx b/integrations/sdk/overview.mdx similarity index 90% rename from for-developers/sdk/overview.mdx rename to integrations/sdk/overview.mdx index debcf8b3..12da14ec 100644 --- a/for-developers/sdk/overview.mdx +++ b/integrations/sdk/overview.mdx @@ -25,10 +25,10 @@ Integrations connect bots to external services and platforms, enabling communica - Trigger events in your bots based on actions in external services - + Learn more about integrations - + Create your first integration @@ -43,10 +43,10 @@ Examples of interfaces in Botpress include: - **Typing Indicator**: Defines the events and actions an integration must implement to use typing indicators supported by the external service - + Learn more about interfaces - + Learn how to implement the HITL indicator interface @@ -67,7 +67,7 @@ Just like bots built in Studio, bots-as-code can: - Define custom events, primarily for scheduling purposes (to trigger self-execution at specified times or intervals) - Subscribe to events from integrations and interfaces to execute business logic - + Create your first bot-as-code @@ -88,7 +88,7 @@ The **HITL integration** is similar to integrations like Zendesk or Freshchat. I The **HITL plugin** contains the logic for human-in-the-loop functionality. It forwards messages to a human agent and allows the agent to respond. The plugin depends on the HITL interface, meaning it can work with any integration that implements it, including the HITL integration. - + Learn how to implement the HITL interface in your integration diff --git a/snippets/folder-component.jsx b/snippets/folder-component.jsx deleted file mode 100644 index 78c5bdaf..00000000 --- a/snippets/folder-component.jsx +++ /dev/null @@ -1,97 +0,0 @@ -export const Files = ({ className = '', children, ...props }) => { - return ( -
- {children} -
- ); -}; - -export const File = ({ name, icon, className = '', ...rest }) => { - return ( -
- - {icon || } - - {name} -
- ); -}; - -export const Folder = ({ name, defaultOpen = false, disabled, children, className = '', ...props }) => { - const [open, setOpen] = useState(defaultOpen); - const [height, setHeight] = useState('0px'); - const [opacity, setOpacity] = useState(0); - const contentRef = useRef(null); - - useEffect(() => { - if (contentRef.current) { - if (defaultOpen) { - const contentHeight = contentRef.current.scrollHeight; - setHeight(`${contentHeight}px`); - setOpacity(1); - } - } - }, [defaultOpen]); - - useEffect(() => { - if (contentRef.current) { - if (open) { - const contentHeight = contentRef.current.scrollHeight; - setHeight(`${contentHeight}px`); - requestAnimationFrame(() => { - setOpacity(1); - }); - } else { - setOpacity(0); - setHeight('0px'); - } - } - }, [open]); - - useEffect(() => { - if (contentRef.current && open) { - const contentHeight = contentRef.current.scrollHeight; - setHeight(`${contentHeight}px`); - } - }, [children, open]); - - const handleToggle = () => { - if (!disabled) { - setOpen(!open); - } - }; - - return ( -
- -
- {children} -
-
- ); -}; - diff --git a/studio/tutorial.mdx b/studio/tutorial.mdx new file mode 100644 index 00000000..ddc28004 --- /dev/null +++ b/studio/tutorial.mdx @@ -0,0 +1,3 @@ +--- +url: "/tutorial" +--- diff --git a/styles.css b/styles.css index 7e7eba79..1db4a039 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,9 @@ +/* Force footer to show on frame mode pages */ +[data-page-mode='frame'] footer, +[data-page-mode='frame'] [data-component='footer'] { + display: flex !important; +} + .transparent-accordion .bg-background-light { background-color: transparent !important; } @@ -35,17 +41,17 @@ } .button { - background-color: #0588f0; - color: white; - text-align: center; - border: 1px solid #0588f0; - font-weight: 500; - padding: .5rem 1rem; - font-size: 0.9rem; - line-height: 130%; - text-decoration: none; - transition: all .2s; - position: relative + background-color: #0588f0; + color: white; + text-align: center; + border: 1px solid #0588f0; + font-weight: 500; + padding: 0.5rem 1rem; + font-size: 0.9rem; + line-height: 130%; + text-decoration: none; + transition: all 0.2s; + position: relative; } .button:hover { @@ -53,46 +59,54 @@ } .discord_banner { - text-align: center; - background-color: light-dark(#fcfcfc, #1a1a1a); - border: 1px solid #626762; - padding: .5rem 1rem; - font-size: 0.9rem; - line-height: 130%; - text-decoration: none; - transition: all .2s; - position: relative + text-align: center; + background-color: light-dark(#fcfcfc, #1a1a1a); + border: 1px solid #626762; + padding: 0.5rem 1rem; + font-size: 0.9rem; + line-height: 130%; + text-decoration: none; + transition: all 0.2s; + position: relative; } .home-columns { - margin-bottom: 0.66em; + /* margin-bottom: 0.66em; */ } +#test { + margin: 0; +} @media (min-width: 768px) { .home-columns { flex: 1 1 0%; - max-width: 33.333% + max-width: 33.333%; } -} -[data-nav-tag="BETA"] { - background-color: light-dark(rgb(255 251 235/.5), rgb(245 158 11/.1)) !important; - color: light-dark(rgb(120 53 15/var(--tw-text-opacity)), rgb(253 230 138/var(--tw-text-opacity))) !important; + .lower-columns { + flex: 1 1 0%; + max-width: 50%; + } } -[data-nav-tag="Plus"] { - background-color: light-dark(#E3EAFD, #07296A) !important; - color: light-dark(#133A9A, #7196F4) !important; +[data-nav-tag='Beta'] { + background-color: light-dark(#e3eafd, #07296a) !important; + color: light-dark(#133a9a, #7196f4) !important; } +[data-nav-tag='Plus'] { + background-color: light-dark(#e3eafd, #07296a) !important; + color: light-dark(#133a9a, #7196f4) !important; +} -[data-nav-tag="Team"] { - background-color: light-dark(#D1FAE4, #0F4C2C) !important; - color: light-dark(#166E3F, #6AE1A1) !important; +[data-nav-tag='Team'] { + background-color: light-dark(#d1fae4, #0f4c2c) !important; + color: light-dark(#166e3f, #6ae1a1) !important; } -@media (min-width: 768px) { .bpWebchat { +@media (min-width: 768px) { + .bpWebchat { /* box-shadow: none !important; */ min-width: 450px; width: 29.7vw !important; @@ -104,7 +118,7 @@ height: 0.9em !important; width: auto !important; aspect-ratio: auto !important; - pointer-events: none + pointer-events: none; } .max-w-xl { /* max-width: 750px; */ @@ -115,7 +129,7 @@ img { background-color: inherit !important; } -[data-component-part="card-content"] { +[data-component-part='card-content'] { font-size: 0.875rem; } @@ -146,7 +160,7 @@ img { width: 40px; height: calc(100vh - 4.64rem); background-color: light-dark(#f7f7f8, #09090b); - border-left: 1px solid light-dark(rgb(226,222,230), rgb(255 255 255/.07)); + border-left: 1px solid light-dark(rgb(226, 222, 230), rgb(255 255 255/0.07)); border-right: none; color: light-dark(#1a1a1a, #fcfcfc); cursor: pointer; @@ -182,8 +196,8 @@ img { z-index: 32; pointer-events: none; background-color: light-dark(#fcfcfc, #1a1a1a); - border: 1px solid light-dark(rgb(226,222,230), rgb(255 255 255/.07)); - border-radius: .75em; + border: 1px solid light-dark(rgb(226, 222, 230), rgb(255 255 255/0.07)); + border-radius: 0.75em; position: absolute; left: 50%; top: 50%; @@ -263,7 +277,7 @@ img { overflow: hidden; pointer-events: auto; min-width: 0; - border-left: 1px solid light-dark(rgb(226,222,230), rgb(255 255 255/.07)); + border-left: 1px solid light-dark(rgb(226, 222, 230), rgb(255 255 255/0.07)); } .bot-panel.resizing { @@ -343,7 +357,7 @@ img { margin: 0; transform: translateY(100%); transition: transform 0.15s cubic-bezier(0.32, 0.72, 0, 1); - border-top: 1px solid light-dark(rgb(226,222,230), rgb(255 255 255/.07)); + border-top: 1px solid light-dark(rgb(226, 222, 230), rgb(255 255 255/0.07)); } .bot-panel-expanded { @@ -395,7 +409,9 @@ img { width: 480px; max-width: 480px; pointer-events: none; - transition: opacity 150ms ease, transform 150ms ease; + transition: + opacity 150ms ease, + transform 150ms ease; opacity: 1; } @@ -404,19 +420,21 @@ img { align-items: center; justify-content: space-between; padding: 0 16px 0 24px; - border: 1px solid light-dark(rgb(var(--gray-950)/.2), rgb(255 255 255/.2)); + border: 1px solid light-dark(rgb(var(--gray-950) / 0.2), rgb(255 255 255/0.2)); border-radius: 16px; background-color: light-dark(rgba(252, 252, 252, 0.8), rgba(26, 26, 26, 0.8)); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.05); pointer-events: auto; - transition: border-color 400ms, opacity 150ms ease; + transition: + border-color 400ms, + opacity 150ms ease; width: 100%; } .ask-ai-input-bubble:focus-within .ask-ai-input-wrapper { - border-color: #0588F0; + border-color: #0588f0; } .ask-ai-input { @@ -464,7 +482,9 @@ img { background-color: light-dark(rgba(5, 136, 240, 0.3), rgba(5, 136, 240, 0.3)); color: white; cursor: pointer; - transition: background-color 0.2s ease, opacity 0.2s ease; + transition: + background-color 0.2s ease, + opacity 0.2s ease; flex-shrink: 0; } @@ -474,7 +494,7 @@ img { } .ask-ai-send-button:not(:disabled) { - background-color: #0588F0; + background-color: #0588f0; } .ask-ai-send-button:disabled { @@ -498,7 +518,7 @@ img { width: calc(100% - 64px); max-width: 320px; } - + .ask-ai-input-bubble-hidden { transform: translateX(-50%) translateY(10px); } @@ -524,4 +544,4 @@ img { .ask-ai-shortcut { display: none; } -} \ No newline at end of file +}