Input: {"body":{"messages":[{"content":"You need to tag the input with the following labels based on the question asked:\nABSOLUTELY_NOT: You are absolutely sure that the answer is \"NO\" to the question.\nPROBABLY_NOT: You are leaning towards \"NO\" to the question.\nAMBIGUOUS: You are unsure about the answer to the question.\nPROBABLY_YES: You are leaning towards \"YES\" to the question.\nABSOLUTELY_YES: You are absolutely sure that the answer is \"YES\" to the question.\n\nYou need to return a mapping of the labels, an explanation and the answer for each label following the format below:\n```\n■is_about_animals:【explanation (where \"explanation\" is answering the question \"is the text about animals?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_lua_code:【explanation (where \"explanation\" is answering the question \"does the text contain Lua code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_python_code:【explanation (where \"explanation\" is answering the question \"does the text contain Python code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_js_code:【explanation (where \"explanation\" is answering the question \"does the text contain JavaScript code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_botpress:【explanation (where \"explanation\" is answering the question \"is the text about Botpress?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_rasa:【explanation (where \"explanation\" is answering the question \"is the text about Rasa?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_flows:【explanation (where \"explanation\" is answering the question \"does the text mention flows?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_api:【explanation (where \"explanation\" is answering the question \"does the text mention the Botpress API?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_enterprise:【explanation (where \"explanation\" is answering the question \"does the text mention Botpress Enterprise?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_workspaces:【explanation (where \"explanation\" is answering the question \"does the text mention workspaces?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_webchat:【explanation (where \"explanation\" is answering the question \"does the text mention the Webchat?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_hitl:【explanation (where \"explanation\" is answering the question \"does the text mention HITL (human in the loop)?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n■END■\n```\n\nundefined\n\n===\nYou should consider the Expert Examples below to help you make your decision.\nIn your \"Analysis\", please refer to the Expert Examples # to justify your decision.","role":"system"},{"content":"Input to tag:\n<|start_input|>\ndocs/execute)  \n   * [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n        \n* [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n         * [AI Task](/docs/ai-task-1)  \n         * [AI Transition](/docs/ai-transition)  \n         * [AI Generate Text](/docs/ai-generate-text)  \n   * [Capture Information](/docs/capture-information)  \n   * [Events](/docs/events-3)  \n   * [Agents](/docs/agents-2)  \n   * [Utilities](/docs/utilities)\n## integrations\n* [Usage](/docs/using-integrations)  \n   * [Asana](/docs/asana-integration)  \n   * [HITL](/docs/hitl-1)  \n   * [Instagram](/docs/instagram)  \n   * [Intercom](/docs/intercom)  \n   * [Line](/docs/line)  \n   * [Messenger](/docs/messenger)  \n   * [Microsoft Teams](/docs/microsoft-teams)  \n   * [Notion](/docs/notion)  \n   * [Slack](/docs/slack)  \n   * [Sunshine Conversations](/docs/sunshine-conversations)  \n   * [Telegram](/docs/telegram)  \n   * [Trello](/docs/trello)  \n   * [Twilio](/docs/twilio)  \n   * [Viber](/docs/viber)  \n   * [Vonage](/docs/vonage)  \n   * [Webhook](/docs/webhook)  \n   * [WhatsApp](/docs/whatsapp)  \n         * [Manual Configuration](/docs/manual-configuration)  \n   * [Zapier](/docs/zapier)  \n   * [Zendesk](/docs/zendesk)\n* [Building](/docs/building-integrations)  \n   * [Getting Started](/docs/getting-started-1)  \n         * [Getting Started](/docs/getting-started-1)  \n         * [Adding Messaging Channel Capabilities](/docs/adding-messaging-channel-capabilities)  \n         * [Adding Actions & Triggers to Botpress Studio](/docs/adding-actions-triggers-to-botpress-studio)  \n         * [Publish your integration on Botpress Hub](/docs/publish-your-integration-on-botpress-hub)  \n   * [Use Your Own LLM](/docs/llm-interfaces)  \n   * [Connect a live agent platform with Botpress](/docs/hitl)  \n   * [Moving Parts](/docs/moving-parts)  \n   * [CLI](/docs/cli)  \n   * [SDK](/docs/sdk)  \n   * [Key Concepts](/docs/key-concepts)  \n         * [Architecture](/docs/architecture)\n/docs/sdk)  \n   * [Key Concepts](/docs/key-concepts)  \n         * [Architecture](/docs/architecture)  \n         * [Tags](/docs/tags)  \n         * [Channels](/docs/channels)  \n         * [Configuration](/docs/configuration)  \n         * [User](/docs/user)  \n         * [Conversations](/docs/conversations-1)  \n         * [Messages](/docs/messages)  \n         * [Event](/docs/event)  \n         * [States](/docs/states-1)  \n         * [Actions](/docs/actions)  \n         * [Definitions](/docs/definitions)  \n         * [Secrets](/docs/secrets)  \n         * [ZUI - Zod schema UI components in Botpress \\[BETA\\]](/docs/zui-zod-schema-ui-components-in-botpress)  \n   * [How to](/docs/states)  \n         * [States](/docs/states)  \n         * [Register & Unregister](/docs/register-unregister)  \n         * [Integrations Actions](/docs/integrations)  \n         * [Integration Events](/docs/integration-events)  \n         * [Handler](/docs/handler)  \n         * [Logging](/docs/logging)  \n         * [Building a Custom Integration](/docs/building-a-custom-integration)\n## Webchat\n* [Webchat](/docs/webchat)  \n   * [Webflow](/docs/webflow)  \n   * [Wix](/docs/wix)  \n   * [Wordpress](/docs/wordpress)\n* [Webchat v1 (deprecated)](/docs/web-chat-v1old)  \n   * [Controlling Web Chat using JavaScript](/docs/controlling-web-chat-using-javascript)  \n   * [Styling your webchat](/docs/chatbot-button)  \n         * [Chatbot Button](/docs/chatbot-button)  \n         * [Chat Header](/docs/chat-header)  \n         * [User Input Area](/docs/user-input-area)  \n         * [Show Bot Info](/docs/show-bot-info)  \n   * [Embedding Webchat](/docs/react-app)  \n         * [React App](/docs/react-app)  \n         * [React Native App](/docs/react-native-app)  \n         * [Web Chat Iframe](/docs/web-chat-iframe)  \n         * [Full Screen Chatbot](/docs/full-screen-chatbot)\n* [Webchat v2](/docs/embedded-webchat)  \n   * [Embedded Webchat](/docs/embedded-webchat)  \n         * [Custom CSS Reference](/docs/custom-css-reference)  \n   * [React Components](/docs/react-js)  \n   * [Webchat Client](/docs/webchat-client)\n## Botpress APIs\n* [Files API](/docs/files-api)\n* [Chat API](/docs/chat-api)\n## Appendix\n* [Safety](/docs/safety)  \n   * [Preventing Abuse](/docs/preventing-abuse)  \n   * [Brand Safety Framework](/docs/brand-safety-framework)\n* [Exporting Data](/docs/exporting-data)  \n   * [Raw Conversations](/docs/exporting-raw-conversations-with-the-botpress-api)  \n   * [Conversation History](/docs/getting-the-conversation-history-from-within-your-bot)  \n   * [Streaming Analytics](/docs/streaming-analytics-from-within-your-bot-with-hooks)  \n   * [Compiled Bot Analytics](/docs/exporting-compiled-bot-analytics-with-the-botpress-api)\nPowered by\n# Files API\n[ Suggest Edits](/edit/files-api)\nThe Files API allows you to upload, download, and manage files and searchable documents for your bots and integrations in Botpress Cloud.\nFiles can be in any text or binary format, and documents (such as PDF, Microsoft Office, HTML, CSV, etc.) can be indexed to be used for semantic search in RAG (Retrieval Augmented Generation) implementations. Files are private by default but can be made publicly accessible through a permanent URL that's unique for each file.\nGetting Started\n[](#getting-started)\n1. Get familiarized with the [API reference](../docs/api-documentation/#files) and the different API endpoints available\n2. Review the [instructions on how to authenticate](../docs/api-documentation/#authentication) with the API.\nExamples\n[](#examples)\nCreating and uploading a file\n[](#creating-and-uploading-a-file)\nIn an Execute Card in your bot\n[](#in-an-execute-card-in-your-bot)\nThe following code snippet can be put in an Execute Card in your bot to create and upload a file that can be accessed by anyone with the file URL and that will be indexed for semantic search:\n> Note: Make sure you have enabled the \"Use the Botpress Client\" setting in your bot's settings in Botpress Studio in order to have access to the `client` global variable, otherwise it will not be accessible and you'll get an error.\nJavaScript\n`const file = await client.uploadFile({\nkey: 'optional_prefix/unique_file_name.txt', // Each file needs a unique key under your bot\ncontent: 'This is a test file',\n})\n`\nOnce the code above runs, the URL to download the file will be available in the `file.url` property.\nBy default the file URL returned will be temporary and change on each request to this endpoint, and will expire after a short period of time and thus should not be stored long-term, but if the file was created with a 'public\\_content' access policy then this URL will be permanent and can be stored long-term.\nUploading from an existing URL\n[](#uploading-from-an-existing-url)\nOr if the file is already available in a URL and you want to download and then upload it to Botpress Cloud you can pass it in the `url` parameter instead of using the `content` parameter:\nJavaScript\n`const file = await client.uploadFile({\nkey: 'unique_file_name.pdf', // Each file needs a unique key under your bot\nurl: 'https://example.com/test.pdf', // This is the external URL where the file is currently located\n})\n`\nUploading a binary file\n[](#uploading-a-binary-file)\nIf you are dealing with a binary file such as a PDF or Microsoft Office document you can also pass a `Buffer` object as the `content` parameter for the file:\nJavaScript\n`const buffer = // This must be a Buffer object containing the binary content of the file\nconst file = await client.uploadFile({\nkey: 'unique_file_name.pdf', // Each file needs a unique key under your bot\ncontent: buffer,\n})\n`\nIn a custom script using the Botpress Client\n[](#in-a-custom-script-using-the-botpress-client)\nIf you're using Javascript or TypeScript the easiest way to interact with the API is using the [Botpress Client](https://www.npmjs.com/package/@botpress/client). You can install the client package by using your favorite package manager:\nnpmpnpmText\n`npm install @botpress/client\n`\n`pnpm install @botpress/client\n`\n`yarn add @botpress/client\n`\nThe Botpress Client will handle the authentication and other details for you, you just need to provide your Botpress PAT (Personal Access Token) to the client and the ID of the bot that the client will access. If your use-case requires accessing multiple bots, you can define as many client instances as needed (one for each bot).\nYou can use the following code snippet to create and upload a file in a custom script using the Botpress Client. Note that in the example below your Botpress PAT (Personal Access Token) and bot ID must be defined in the environment variables `BOTPRESS_PAT` and `BOTPRESS_BOT_ID` respectively.\nJavaScript\n`import { Client } from '@botpress/client'\nconst client = new Client({\ntoken: process.env.BOTPRESS_PAT,\nbotId: process.env.BOTPRESS_BOT_ID,\n})\nconst file = await client.uploadFile({\nkey: 'optional_prefix/unique_file_name.txt',\ncontent: 'This is a test file',\n})\n`\nIn a custom script using an HTTP client\n[](#in-a-custom-script-using-an-http-client)\nIf you can't use the Botpress Client (e.g. you can't install the package or you're working with a different programming language) you can also use any HTTP client to make requests to the API directly.\nPlease note that when calling the API directly, an HTTP request to the Botpress API (specifying the file size beforehand) will be needed to create the empty file first, and a separate HTTP request will be needed to upload the file content to the unique upload URL provided in the response of the first request.\nAdditionally, if you need to access the file URL right away a third request to the \"Get File\" API endpoint will be needed to get the URL of the file after it has been uploaded.\nHere's an example on how to do this using the native `fetch()` function in Javascript/TypeScript, note that your Botpress PAT will need to be defined in the environment variable `BOTPRESS_PAT`:\nJavaScript\n`` const fileContent = 'Here goes the content of your file'\nconst buffer = Buffer.from(fileContent)\n// Step 1: Create the file in Botpress Cloud.\n// Please note that specifying the file size (in raw bytes, not characters) is required when calling this endpoint.\nconst result = await fetch('https://api.botpress.cloud/v1/files', {\nmethod: 'PUT',\nheaders: {\n'Content-Type': 'application/json',\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\nbody: JSON.stringify({\nkey: 'unique_file_name.txt',\nsize: buffer.byteLength,\n}),\n})\nconst response = await result.json()\n// Step 2: Upload the file content to the unique upload URL provided for the created file.\nawait fetch(response.file.uploadUrl, {\nmethod: 'PUT',\nbody: buffer,\n})\n// The variable below will contain the URL to download the file content uploaded above. If the file was\n// created with the 'public_content' access policy it will be a permanent URL that you can store long-term,\n// otherwise it will contain a temporary pre-signed URL that expires after a short period of time.\n// If you need to get a new URL, you can always use the `getFile` API endpoint.\nconst downloadUrl = response.file.url\n``\nAdding tags to a file\n[](#adding-tags-to-a-file)\nYou can add custom tags to a file by passing the `tags` parameter when it's created. Tags allow you to organize and classify files in any way you see fit, and can be specified as a filter when listing or searching files.\nJavaScript\n`const file = await client.uploadFile({\nkey: 'test.txt',\ncontent: 'This is a test file',\ntags: {\n// Tags are optional but are useful for filtering files by a custom criteria you choose when using the \"List Files\" or \"Search Files\" API endpoints. You can change or remove the tags below based on your needs.\ncategory: 'Sales',\nknowledgeBaseName: 'Client Questions',\n},\n})\n`\nCreating a public file\n[](#creating-a-public-file)\nBy default all files are private and can only be accessed by the bot that created them. If you need to make a file publicly accessible by anyone you can assign the `public_content` access policy to the file:\nJavaScript\n`const file = await client.uploadFile({\nkey: 'test.txt',\ncontent: 'This is a public file',\naccessPolicies: ['public_content'],\n})\n`\nIf you only want to allow all the integrations installed in the bot to access the file rather than making it fully public, you can just assign the `integrations` access policy instead:\nJavaScript\n`const file = await client.uploadFile({\nkey: 'test.txt',\ncontent: 'This is a file that can be accessed by all integrations in a bot',\naccessPolicies: ['integrations'],\n})\n`\nCreating an indexed file\n[](#creating-an-indexed-file)\nIf you need to index a file for semantic search you can use the `index` parameter when creating the file.\nJavaScript\n`const file = await client.uploadFile({\nkey: 'test.txt',\ncontent: 'This is a test file',\nindex: true,\n})\n`\nSupported file formats\n[](#supported-file-formats)\nThe following file formats are supported for indexing:\n| Format   | File Extension | MIME Type       |\n| -------- | -------------- | --------------- |\n| PDF      | .pdf           | application/pdf |\n| HTML     | .html          | text/html       |\n| Text     | .txt           | text/plain      |\n| Markdown | .md            | text/markdown   |\nNotes on indexing:\n[](#notes-on-indexing)\n* The file it will initially have a status of \"indexing\\_pending\" and will be indexed asynchronously. The time it takes to index the file will depend on the file size and the current load on the system.\n* You can check the status of the file by calling the [Get File](../docs/api-documentation/#get-file) endpoint and checking that the `file.status` property has changed to \"indexing\\_completed\".\n* If the indexing failed the status will be set to \"indexing\\_failed\" and the reason of the failure will be available in the `failedStatusReason` property of the file.\nGetting the file's metadata\n[](#getting-the-files-metadata)\nTo get the details of a file you can use the [Get File](../docs/api-documentation/#get-file) API endpoint.\nYou can also use this endpoint to retrieve a new temporary pre-signed URL to download a file if the previous pre-signed URL has already expired.\nUsing the Botpress ClientCalling the API directly\n` const file = await client.getFile('YOUR_FILE_ID')\n`\n`` const result = await fetch('https://api.botpress.cloud/v1/files/YOUR_FILE_ID', {\nmethod: 'GET',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\n})\nconst response = await result.json()\nconst file = response.file\n``\nListing existing files of a bot\n[](#listing-existing-files-of-a-bot)\nTo list all the files of a bot you can use the [List Files](../docs/api-documentation/#list-files) API endpoint.\nUsing the Botpress ClientCalling the API directly\n`const res = await client.listFiles()\nconst files = res.data.files\n`\n`` const result = await fetch('https://api.botpress.cloud/v1/files', {\nmethod: 'GET',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\n})\nconst response = await result.json()\nconst files = response.files\n``\nFiltering by tags\n[](#filtering-by-tags)\nIf you need to filter files by tags, you can just pass the `tags` parameter which should be an object with key-value pairs of tags a file must have in order to be returned. Tag filtering works in an \"AND\" fashion, so only the files that have all the specified tags will be returned.\nUsing the Botpress ClientCalling the API Directly\n`const res = await client.listFiles({\ntags: {\ncategory: 'Sales',\n},\n})\n`\n`` const tags = {\ncategory: 'Sales',\n}\nconst result = await fetch('https://api.botpress.cloud/v1/files?tags=' + encodeURIComponent(JSON.stringify(tags)), {\nmethod: 'GET',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\n})\n``\n> ## ���\n>\n> Calling the API Directly\n>\n> If you're making the HTTP request directly to the API please note that you'll need to pass the tags parameter as a JSON-serialized, URL-encoded string (the Botpress Client handles this automatically for you).\nPagination\n[](#pagination)\nThe [List Files](../docs/api-documentation/#list-files) API endpoint will return by default the 20 most recent files your bot has. If you need to list older files you can use the `nextToken` property returned in the API response to retrieve the next page (if any) of files. The `nextToken` will be included for each page if there are files remaining to be listed.\nFor example:\nJavaScript\n`let res = await client.listFiles()\nconst files = res.data.files\n// You can put this in a loop to retrieve all the files if needed.\nif (res.data.nextToken) {\nres = await client.listFiles({ nextToken: res.data.nextToken })\nfiles.push(...res.data.files)\n}\n`\nUpdating the file metadata\n[](#updating-the-file-metadata)\nOnly the tags and access policies of a file can be updated.\nHere's an example of how to update the access policies and tags of a file using the Botpress Client:\nUsing the Botpress ClientCalling the API Directly\n`` await client.updateFile({\nid: 'YOUR_FILE_ID',\naccessPolicies: ['integrations'], // This value will replace the existing access policies of the file.\ntags: {\n// This acts as a \"patch\" or partial update, so only the tags specified here will be updated, the rest will remain unchanged. If you need to delete an existing tag, you can set it to a `null` value.\ncategory: 'Support', // This tag will be updated.\nknowledgeBaseName: null, // This tag will be deleted.\nsubcategory: 'Technical', // This tag will be added.\n// Any other tags not specified here will remain unchanged.\n},\n})\n``\n`` await fetch(\n'https://api.botpress.cloud/v1/files/YOUR_FILE_ID',\n{\nmethod: 'PUT',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\nbody: {\naccessPolicies: ['integrations'], // This value will replace the existing access policies of the file.\ntags: {\n// This acts as a \"patch\" or partial update, so only the tags specified here will be updated, the rest will remain unchanged. If you need to delete an existing tag, you can set it to a `null` value.\ncategory: 'Support', // This tag will be updated.\nknowledgeBaseName: null, // This tag will be deleted.\nsubcategory: 'Technical', // This tag will be added.\n// Any other tags not specified here will remain unchanged.\n},\n},\n}\n)\n``\nUpdating file content\n[](#updating-file-content)\nIf you need to update the content of a file, you can create a new file with the updated content and then delete the old file. The file ID will change in this case.\nDeleting a file\n[](#deleting-a-file)\nTo delete a file you can use the \"Delete File\" API endpoint.\nUsing the Botpress ClientCalling the API Directly\n`await client.deleteFile('YOUR_FILE_ID')\n`\n`` await fetch('https://api.botpress.cloud/v1/files/YOUR_FILE_ID', {\nmethod: 'DELETE',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\n})\n``\nSearching files\n[](#searching-files)\nTo run a semantic search on your bot's files you can use the [Search Files](/api-documentation/#search-files) API endpoint. This is particularly useful for RAG (Retrieval Augmented Generation) implementations.\nUsing the Botpress ClientCalling the API Directly\n`const res = await client.searchFiles({\nquery: 'what are the most popular products of your company?', // This is the natural language query (e.g. a user's question) to be used for running a semantic search on the files of the bot.\ncontextDepth: 1, // Optional (default: 0), allows you prepend and append the surrounding context to each matching passage in the search results\ntags: {\n// Optional, allows you to only search files that match the specified tags. Useful if you only want to search a subset of the bot's files.\ncategory: 'Support',\nsubcategory: 'Technical',\n},\nlimit: 30, // Default is 20, maximum is 50 results\n})\nconst passages = res.data.passages\nfor (const passage of passages) {\n// You can use passage.content here to retrieve the content (including surrounding context, if any) of each matching passage\n}\n`\n`` const params = new URLSearchParams({\nquery: 'what are the most popular products of your company?',\ntags: JSON.stringify({\ncategory: 'Support',\nsubcategory: 'Technical',\n}),\n})\nconst result = await fetch('https://api.botpress.cloud/v1/files/search?' + params.toString(), {\nmethod: 'GET',\nheaders: {\nAuthorization: `Bearer ${process.env.BOTPRESS_PAT}`,\n},\n})\nconst response = await result.json()\nconst passages = response.passages\n``\nYou can check the [API reference](/api-documentation/#search-files) for more details on the properties available for each passage object returned in the response.\nUsing the search results for RAG\n[](#using-the-search-results-for-rag)\nYou can use the search results to provide relevant information to a chatbot for generating a response to a user's question.\nHere's an example of a simple RAG (Retrieval Augmented Generation) implementation that shows how you can use the ChatGPT large language model (through the OpenAI API) and the search results provided by our API to answer a user's question:\nJavaScript\n`` import OpenAI from 'openai' // You'll need to install this package first using your favorite package manager\nconst openai = new OpenAI({ apiKey: 'YOUR_OPENAI_API_KEY' })) // Change this for your own OpenAI API key\nconst userQuestion = 'Which are the most popular products of your company?' // This will come from the user's input\nconst res = await client.searchFiles({\nquery: userQuestion,\ncontextDepth: 1, // This number can be increased to pass more context to the model for each matching passage\n})\nconst relevantInformation = res.data.passages.map(passage => passage.content).join(\"\\n\\n----------\\n\\n\")\nconst answer = await openai.chat.completions.create({\nmodel: 'gpt-3.5-turbo', //  This can be changed for any other OpenAI model available here: https://platform.openai.com/docs/models\nmessages: [\n{\nrole: 'system',\n// You can change the text below to include any additional instructions to the model\ncontent: \"You are a helpful assistant that answers the user's question based only on the relevant information you are provided along with the question.\",\n},\n{\nrole: 'user',\ncontent: `## RELEVANT INFORMATION: \\n\\n ${relevantInformation}\\n\\n` +\n`## ANSWER THE FOLLOWING USER'S QUESTION: \\n\\n ${userQuestion}`,\n},\n],\n})\n``\nSecurity\n[](#security)\nAccess Policies\n[](#access-policies)\nA file can have a list of special access policies:\n* `public_content`: Unauthenticated users can read contents (but not metadata) of the file through a unique permanent URL provided by the API for each file. Without this policy the file URL returned by the API will be temporary and will expire after a short period of time.\n* `integrations`: Grants read, search, list access to all integrations of the bot that owns the file.\nPermissions\n[](#permissions)\n| Principal                                            | Permissions                                                                                |\n| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |\n| Public (unauthenticated/unauthorized users)          | Can only download files that have the public\\_content access policy.                                                      |\n| Bot                                                  | Owns and manages its files with full permissions to access and manage them, regardless of the user that created the file. |\n| Integration                                          | Has all permissions on the files that were created by that integration for the bot they are installed on.                 |\n| Viewer workspace member                              | Can read, search, and list all files for the bot, regardless of creator, but cannot create or delete files.               |\n| Developer, Manager or Administrator workspace member | Has all permissions on the bot's files, regardless of creator.                                                            |\n| Billing Manager workspace member                     | No permissions on files.                                                                                |\n> ## ���\n>\n> Note\n>\n> The [List Files](../docs/api-documentation/#list-files) API endpoint will filter out files that are not accessible to the user calling that API endpoint.\nPricing\n[](#pricing)\nThere are two types of storage: File Storage and Vector DB Storage. All files count toward your workspace's File Storage usage. Indexed files also count toward your workspace's Vector DB Storage usage.\nFor full details on pricing please check our [Pricing page](https://botpress.com/pricing).\nQuotas/Limits\n[](#quotaslimits)\n* Maximum file size: 100 MB\n* Rate limits: [same as all other endpoints](../docs/preventing-abuse) of our public API\n* Tags  \n   * As defined in the [Limits and Quotas of Botpress Cloud](../docs/limits-and-quotas-of-botpress-cloud)\n* Search  \n   * Query: 1 KB maximum  \n   * Maximum number of results: 50\nUpdated 2 months ago\n---\n* [Table of Contents](#)\n* * [Getting Started](#getting-started)  \n   * [Examples](#examples)  \n   * [Creating and uploading a file](#creating-and-uploading-a-file)  \n         * [In an Execute Card in your bot](#in-an-execute-card-in-your-bot)  \n         * [In a custom script using the Botpress Client](#in-a-custom-script-using-the-botpress-client)  \n         * [In a custom script using an HTTP client](#in-a-custom-script-using-an-http-client)  \n         * [Adding tags to a file](#adding-tags-to-a-file)  \n         * [Creating a public file](#creating-a-public-file)  \n         * [Creating an indexed file](#creating-an-indexed-file)  \n         * [Getting the file's metadata](#getting-the-files-metadata)  \n         * [Listing existing files of a bot](#listing-existing-files-of-a-bot)  \n         * [Updating the file metadata](#updating-the-file-metadata)  \n         * [Deleting a file](#deleting-a-file)  \n         * [Searching files](#searching-files)  \n   * [Security](#security)  \n         * [Access Policies](#access-policies)  \n         * [Permissions](#permissions)  \n   * [Pricing](#pricing)  \n   * [Quotas/Limits](#quotaslimits)[Jump to Content](#content)\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\n---\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\nGuides\nMoon (Dark Mode)Sun (Light Mode)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\nFind\nSearch\n## Home\n* [Botpress Documentation](/docs/home)\n## Getting Started\n* [Build](/docs/build)\n* [Deploy](/docs/deploy)\n* [Monitor](/docs/monitor)\n## DASHBOARD\n* [Workspace](/docs/workspace)  \n   * [Home](/docs/home-1)  \n   * [Members](/docs/members)  \n   * [Audits](/docs/audits)  \n   * [Your integrations](/docs/your-integrations)  \n   * [Usage](/docs/usage-2)  \n   * [Settings](/docs/settings)  \n   * [Profile Setting](/docs/user-profile)\n* [Bot](/docs/bot)  \n   * [Overview](/docs/overview-1)  \n   * [Integrations](/docs/integrations-1)  \n   * [Webchat](/docs/webchat-1)  \n   * [Logs](/docs/logs)  \n   * [Conversations](/docs/conversations)  \n   * [Analytics](/docs/analytics-1)  \n   * [Events](/docs/events-2)  \n   * [Issues](/docs/issues)  \n   * [Configuration variables](/docs/configuration-variables-1)\n## STUDIO\n* [Interface](/docs/interface)  \n   * [Nodes](/docs/nodes)  \n   * [Home](/docs/home-2)  \n   * [Flows](/docs/studio-interface-flows)  \n   * [Knowledge Base](/docs/knowledge-base)  \n   * [Tables](/docs/tables)  \n   * [Agents](/docs/agents)  \n         * [Summary Agent](/docs/summary-agent)  \n         * [Personality Agent](/docs/personality-agent)  \n         * [Policy Agent](/docs/policy-agent)  \n         * [Translator Agent](/docs/translator-agent)  \n         * [Knowledge Agent](/docs/knowledge-agent)  \n         * [HITL Agent](/docs/hitl-agent)  \n         * [Vision Agent](/docs/vision-agent)  \n         * [Analytics Agent](/docs/analytics-agent)  \n   * [Library](/docs/library)  \n   * [Hooks](/docs/hooks)  \n   * [Integrations](/docs/integrations-3)  \n   * [Schemas](/docs/schemas)  \n   * [Card Hub](/docs/card-hub)  \n   * [Versions](/docs/versions-1)  \n   * [Chatbot Settings](/docs/chatbot-settings-1)  \n   * [Find](/docs/find)  \n   * [Variables](/docs/variables)  \n   * [Card Tray](/docs/card-tray)  \n   * [Debugger, Logs & JSON](/docs/debugger-logs-json)  \n   * [Emulator](/docs/emulator)  \n   * [Keyboard Shortcuts](/docs/keyboard-shortcuts)  \n   * [Commands](/docs/studio-commands)  \n   * [Studio Preferences](/docs/studio-preferences)  \n   * [Import & Export](/docs/import-export-bots)\n* [Cards](/docs/cards)  \n   * [Send Messages](/docs/send-messages)  \n   * [Execute](/docs/execute)  \n   * [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n        \n* [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n         * [AI Task](/docs/ai-task-1)  \n         * [AI Transition](/docs/ai-transition)  \n         * [AI Generate Text](/docs/ai-generate-text)  \n   * [Capture Information](/docs/capture-information)  \n   * [Events](/docs/events-3)  \n   * [Agents](/docs/agents-2)\n<|end_input|>\n\nAnswer with this following format:\n```\n■is_about_animals:【explanation (where \"explanation\" is answering the question \"is the text about animals?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_lua_code:【explanation (where \"explanation\" is answering the question \"does the text contain Lua code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_python_code:【explanation (where \"explanation\" is answering the question \"does the text contain Python code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_js_code:【explanation (where \"explanation\" is answering the question \"does the text contain JavaScript code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_botpress:【explanation (where \"explanation\" is answering the question \"is the text about Botpress?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_rasa:【explanation (where \"explanation\" is answering the question \"is the text about Rasa?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_flows:【explanation (where \"explanation\" is answering the question \"does the text mention flows?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_api:【explanation (where \"explanation\" is answering the question \"does the text mention the Botpress API?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_enterprise:【explanation (where \"explanation\" is answering the question \"does the text mention Botpress Enterprise?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_workspaces:【explanation (where \"explanation\" is answering the question \"does the text mention workspaces?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_webchat:【explanation (where \"explanation\" is answering the question \"does the text mention the Webchat?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_hitl:【explanation (where \"explanation\" is answering the question \"does the text mention HITL (human in the loop)?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n■END■\n```\n\nFormat cheatsheet:\n```\n■label:【explanation】:x■\n```\n\nWhere `x` is one of the following: ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES\n\nRemember: In your `explanation`, please refer to the Expert Examples # (and quote them) that are relevant to ground your decision-making process.\nThe Expert Examples are there to help you make your decision. They have been provided by experts in the field and their answers (and reasoning) are considered the ground truth and should be used as a reference to make your decision when applicable.\nFor example, you can say: \"According to Expert Example #1, ...\"","role":"user","type":"text"}],"meta":{"integrationName":"zai","promptCategory":"zai:zai.label","promptSource":"zai:zai.label:default"},"model":"fast","signal":{},"stopSequences":["■END■"]},"method":"POST","url":"https://api.botpress.cloud/v2/cognitive/generate-text"}

Output:
■is_about_animals:【The text is a technical documentation about Botpress features, APIs, and integrations. It contains no references to animals, animal behavior, biology, or related topics.】:ABSOLUTELY_NOT■

■contains_lua_code:【All code snippets are in JavaScript/TypeScript and shell commands; there is no Lua syntax or `function` definitions typical of Lua.】:ABSOLUTELY_NOT■

■contains_python_code:【The document includes only JavaScript/TypeScript examples and shell commands. No Python (`def`, `import`, etc.) code appears.】:ABSOLUTELY_NOT■

■contains_js_code:【Multiple code blocks are explicitly labelled “JavaScript” and use JS syntax (e.g., `const file = await client.uploadFile({ ... })`).】:ABSOLUTELY_YES■

■is_botpress:【The entire passage describes Botpress documentation, APIs, studio, webchat, integrations, and the Botpress Cloud platform.】:ABSOLUTELY_YES■

■is_rasa:【There is no mention of Rasa, its architecture, or any Rasa‑specific terminology.】:ABSOLUTELY_NOT■

■has_flows:【The text repeatedly references “Flow Logic”, “Flows”, and navigation items such as “Flows” under the Studio section, indicating that flows are discussed.】:ABSOLUTELY_YES■

■has_api:【Sections titled “## Botpress APIs”, “Files API”, “Chat API”, and numerous API endpoint examples are present.】:ABSOLUTELY_YES■

■has_enterprise:【The document never mentions “Botpress Enterprise”, “Enterprise edition”, or related licensing terms.】:ABSOLUTELY_NOT■

■has_workspaces:【Multiple references to “Workspace”, “Viewer workspace member”, “Developer, Manager or Administrator workspace member”, and related navigation items appear.】:ABSOLUTELY_YES■

■has_webchat:【The term “Webchat” appears many times, with dedicated sections and links (e.g., “## Webchat”, “Webchat v1”, “Webchat v2”).】:ABSOLUTELY_YES■

■has_hitl:【The abbreviation “HITL” (human in the loop) is mentioned repeatedly in integration lists and agent descriptions.】:ABSOLUTELY_YES■


Input: {"body":{"messages":[{"content":"You need to tag the input with the following labels based on the question asked:\nABSOLUTELY_NOT: You are absolutely sure that the answer is \"NO\" to the question.\nPROBABLY_NOT: You are leaning towards \"NO\" to the question.\nAMBIGUOUS: You are unsure about the answer to the question.\nPROBABLY_YES: You are leaning towards \"YES\" to the question.\nABSOLUTELY_YES: You are absolutely sure that the answer is \"YES\" to the question.\n\nYou need to return a mapping of the labels, an explanation and the answer for each label following the format below:\n```\n■is_about_animals:【explanation (where \"explanation\" is answering the question \"is the text about animals?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_lua_code:【explanation (where \"explanation\" is answering the question \"does the text contain Lua code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_python_code:【explanation (where \"explanation\" is answering the question \"does the text contain Python code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_js_code:【explanation (where \"explanation\" is answering the question \"does the text contain JavaScript code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_botpress:【explanation (where \"explanation\" is answering the question \"is the text about Botpress?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_rasa:【explanation (where \"explanation\" is answering the question \"is the text about Rasa?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_flows:【explanation (where \"explanation\" is answering the question \"does the text mention flows?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_api:【explanation (where \"explanation\" is answering the question \"does the text mention the Botpress API?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_enterprise:【explanation (where \"explanation\" is answering the question \"does the text mention Botpress Enterprise?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_workspaces:【explanation (where \"explanation\" is answering the question \"does the text mention workspaces?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_webchat:【explanation (where \"explanation\" is answering the question \"does the text mention the Webchat?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_hitl:【explanation (where \"explanation\" is answering the question \"does the text mention HITL (human in the loop)?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n■END■\n```\n\nundefined\n\n===\nYou should consider the Expert Examples below to help you make your decision.\nIn your \"Analysis\", please refer to the Expert Examples # to justify your decision.","role":"system"},{"content":"Input to tag:\n<|start_input|>\n agent.\n**hitlStopped**: Tells the bot that the conversation with the live agent has ended.\nindex.ts\n`// index.ts\n// ...\nexport default new bp.Integration({\n// ...previously implemented logic\nhandler: async ({ req, client: botpressClient, ctx, logger }) => {\nconst liveAgentEvent = JSON.parse(req.body);\nswitch (liveAgentEvent.eventType) {\ncase 'newMessage':\n// ...\nbreak;\ncase 'ticketAssigned':\n// Emit an event to inform the bot that HITL has been assigned\nawait botpressClient.createEvent({\ntype: 'hitlAssigned',\npayload: {\nconversationId: conversation.id,\nuserId: user.id,\n},\n});\nbreak;\ncase 'ticketSolved':\n// Emit an event to inform the bot that HITL has been stopped\nawait botpressClient.createEvent({\ntype: 'hitlStopped',\npayload: {\nconversationId: conversation.id,\n},\n});\nbreak;\n}\n},\n});\n`\nFull Example\n[](#full-example)\n`// index.ts\nimport * as sdk from \"@botpress/sdk\";\nimport * as bp from \".botpress\";\n// Replace with your actual platform client library\nimport AgentHandoffPlatformClient from \"./agent-handoff-client\";\n// Initialize the integration\nexport default new bp.Integration({\n// Register method to set the webhook when configuration is saved\nregister: async ({ webhookUrl }) => {\n// Set the webhook to be triggered when a live agent responds\nAgentHandoffPlatformClient.setWebhook(webhookUrl);\n},\n// Unregister method to remove the webhook when integration is uninstalled\nunregister: async ({ webhookUrl }) => {\n// Remove the webhook when the integration is uninstalled\nAgentHandoffPlatformClient.deleteWebhook(webhookUrl);\n},\n// Define the HITL actions\nactions: {\n// Create a user on both Botpress and the agent handoff platform\ncreateUser: async ({ client: botpressClient }) => {\n// Create a user on the agent handoff platform\nconst userOnAgentPlatform = AgentHandoffPlatformClient.createUser();\n// Create a user on Botpress\nconst { user: botpressUser } = await botpressClient.getOrCreateUser({\ntags: {\n// Link the Botpress user with the user on the agent handoff platform\nagentHandoffPlatformUserId: userOnAgentPlatform.id,\n},\n});\nreturn {\nuserId: botpressUser.id,\n};\n},\n// Start a HITL session by creating a conversation on both platforms\nstartHitl: async ({ client: botpressClient, input }) => {\nconst { user } = await botpressClient.getUser({\n// Retrieve the user ID created in the createUser action\nid: input.userId,\n});\n// These properties are provided from the \"Escalate to a Human\" action in the Studio\nconst { title, description } = input;\n// Create a ticket on the agent handoff platform\nconst ticket = AgentHandoffPlatformClient.createTicket({\nticketTitle: title,\nticketDescription: description,\n});\n// Create a conversation in Botpress\nconst { conversation } = await botpressClient.getOrCreateConversation({\nchannel: \"hitl\",\ntags: {\n// Link the ticket with the Botpress conversation\nticketId: ticket.id,\n},\n});\nreturn {\nconversationId: conversation.id,\n};\n},\n// Stop a HITL session by closing the conversation on the agent handoff platform\nstopHitl: async ({ client: botpressClient, input }) => {\nconst { conversation } = await botpressClient.getConversation({\nid: input.conversationId,\n});\nconst ticketId = conversation.tags.ticketId;\n// Close the ticket on the agent handoff platform\nAgentHandoffPlatformClient.closeTicket({ ticketId });\nreturn {};\n},\n},\n// Define the HITL channel to send messages from the end user to the live agent\nchannels: {\nhitl: {\nmessages: {\n// Send a message from the end user to the live agent\ntext: async ({ client, payload }) => {\nconst { text: userMessage, conversation, userId } = payload;\n// Retrieve the ticket ID that was set in the startHitl action\nconst ticketId = conversation.tags.ticketId;\n// Use the agent handoff platform's API to send the message\nAgentHandoffPlatformClient.sendMessage(ticketId, userId, userMessage);\n},\n},\n},\n},\n// Handler to process messages sent from the live agent to the end user\nhandler: async ({ req, client: botpressClient }) => {\nconst liveAgentEvent = JSON.parse(req.body);\n// Fetch the Botpress user based on the user ID from the agent handoff platform\nconst { user } = await botpressClient.getOrCreateUser({\ntags: {\nagentHandoffPlatformUserId: liveAgentEvent.userId,\n},\n});\n// Retrieve or create a conversation in Botpress associated with the ticket ID\nconst { conversation } = await botpressClient.getOrCreateConversation({\nchannel: \"hitl\",\ntags: {\nticketId: liveAgentEvent.ticketId,\n},\n});\nswitch (liveAgentEvent.eventType) {\ncase \"newMessage\":\n// Send the received message from the live agent to the end user\nawait botpressClient.createMessage({\ntype: \"text\",\nuserId: user.id,\nconversationId: conversation.id,\npayload: { text: liveAgentEvent.message },\n});\nbreak;\ncase \"ticketAssigned\":\n// Emit an event to inform the bot that HITL has been assigned\nawait botpressClient.createEvent({\ntype: \"hitlAssigned\",\npayload: {\nconversationId: conversation.id,\nuserId: user.id,\n},\n});\nbreak;\ncase \"ticketSolved\":\n// Emit an event to inform the bot that HITL has been stopped\nawait botpressClient.createEvent({\ntype: \"hitlStopped\",\npayload: {\nconversationId: conversation.id,\n},\n});\nbreak;\n}\n},\n});\n`\nProduction Example\n[](#production-example)\nFor a production-grade implementation, you can refer to the Zendesk integration maintained by the Botpress team. Check it out [here](https://github.com/botpress/botpress/tree/master/integrations/zendesk).\nHaving difficulties with HITL Interfaces?\n[](#having-difficulties-with-hitl-interfaces)\nContact us at [\\[email protected\\]](/cdn-cgi/l/email-protection#2941405d4504414c4559694b465d595b4c5a5a074a4644) with as much details as possible about your company and your use case.\nUpdated 17 days ago\n---\n* [Table of Contents](#)\n* * [How HITL Works in Botpress](#how-hitl-works-in-botpress)  \n   * [Configuring the Integration Definition](#configuring-the-integration-definition)  \n         * [Tags](#tags)  \n   * [Implementing the HITL Logic](#implementing-the-hitl-logic)  \n         * [1\\. Add Register & Unregister Methods](#1-add-register--unregister-methods)  \n         * [2\\. Implement Actions](#2-implement-actions)  \n         * [3\\. Send Messages from End User to Live Agent](#3-send-messages-from-end-user-to-live-agent)  \n         * [4\\. Send Messages from Live Agent to End User](#4-send-messages-from-live-agent-to-end-user)  \n         * [5\\. Inform Bot When HITL Started and Stopped](#5-inform-bot-when-hitl-started-and-stopped)  \n   * [Full Example](#full-example)  \n   * [Production Example](#production-example)  \n   * [Having difficulties with HITL Interfaces?](#having-difficulties-with-hitl-interfaces)[Jump to Content](#content)\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\n---\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\nGuides\nMoon (Dark Mode)Sun (Light Mode)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\nRaw Conversations\nSearch\n## Home\n* [Botpress Documentation](/docs/home)\n## Getting Started\n* [Build](/docs/build)\n* [Deploy](/docs/deploy)\n* [Monitor](/docs/monitor)\n## DASHBOARD\n* [Workspace](/docs/workspace)  \n   * [Home](/docs/home-1)  \n   * [Members](/docs/members)  \n   * [Audits](/docs/audits)  \n   * [Your integrations](/docs/your-integrations)  \n   * [Usage](/docs/usage-2)  \n   * [Settings](/docs/settings)  \n   * [Profile Setting](/docs/user-profile)\n* [Bot](/docs/bot)  \n   * [Overview](/docs/overview-1)  \n   * [Integrations](/docs/integrations-1)  \n   * [Webchat](/docs/webchat-1)  \n   * [Logs](/docs/logs)  \n   * [Conversations](/docs/conversations)  \n   * [Analytics](/docs/analytics-1)  \n   * [Events](/docs/events-2)  \n   * [Issues](/docs/issues)  \n   * [Configuration variables](/docs/configuration-variables-1)\n## STUDIO\n* [Interface](/docs/interface)  \n   * [Nodes](/docs/nodes)  \n   * [Home](/docs/home-2)  \n   * [Flows](/docs/studio-interface-flows)  \n   * [Knowledge Base](/docs/knowledge-base)  \n   * [Tables](/docs/tables)  \n   * [Agents](/docs/agents)  \n         * [Summary Agent](/docs/summary-agent)  \n         * [Personality Agent](/docs/personality-agent)  \n         * [Policy Agent](/docs/policy-agent)  \n         * [Translator Agent](/docs/translator-agent)  \n         * [Knowledge Agent](/docs/knowledge-agent)  \n         * [HITL Agent](/docs/hitl-agent)  \n         * [Vision Agent](/docs/vision-agent)  \n         * [Analytics Agent](/docs/analytics-agent)  \n   * [Library](/docs/library)  \n   * [Hooks](/docs/hooks)  \n   * [Integrations](/docs/integrations-3)  \n   * [Schemas](/docs/schemas)  \n   * [Card Hub](/docs/card-hub)  \n   * [Versions](/docs/versions-1)  \n   * [Chatbot Settings](/docs/chatbot-settings-1)  \n   * [Find](/docs/find)  \n   * [Variables](/docs/variables)  \n   * [Card Tray](/docs/card-tray)  \n   * [Debugger, Logs & JSON](/docs/debugger-logs-json)  \n   * [Emulator](/docs/emulator)  \n   * [Keyboard Shortcuts](/docs/keyboard-shortcuts)  \n   * [Commands](/docs/studio-commands)  \n   * [Studio Preferences](/docs/studio-preferences)  \n   * [Import & Export](/docs/import-export-bots)\n* [Cards](/docs/cards)  \n   * [Send Messages](/docs/send-messages)  \n   * [Execute](/docs/execute)  \n   * [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n        \n* [Webchat](/docs/webchat-2)  \n   * [Flow Logic](/docs/flow-logic)  \n   * [AI](/docs/ai)  \n         * [AI Task](/docs/ai-task-1)  \n         * [AI Transition](/docs/ai-transition)  \n         * [AI Generate Text](/docs/ai-generate-text)  \n   * [Capture Information](/docs/capture-information)  \n   * [Events](/docs/events-3)  \n   * [Agents](/docs/agents-2)  \n   * [Utilities](/docs/utilities)\n## integrations\n* [Usage](/docs/using-integrations)  \n   * [Asana](/docs/asana-integration)  \n   * [HITL](/docs/hitl-1)  \n   * [Instagram](/docs/instagram)  \n   * [Intercom](/docs/intercom)  \n   * [Line](/docs/line)  \n   * [Messenger](/docs/messenger)  \n   * [Microsoft Teams](/docs/microsoft-teams)  \n   * [Notion](/docs/notion)  \n   * [Slack](/docs/slack)  \n   * [Sunshine Conversations](/docs/sunshine-conversations)  \n   * [Telegram](/docs/telegram)  \n   * [Trello](/docs/trello)  \n   * [Twilio](/docs/twilio)  \n   * [Viber](/docs/viber)  \n   * [Vonage](/docs/vonage)  \n   * [Webhook](/docs/webhook)  \n   * [WhatsApp](/docs/whatsapp)  \n         * [Manual Configuration](/docs/manual-configuration)  \n   * [Zapier](/docs/zapier)  \n   * [Zendesk](/docs/zendesk)\n* [Building](/docs/building-integrations)  \n   * [Getting Started](/docs/getting-started-1)  \n         * [Getting Started](/docs/getting-started-1)  \n         * [Adding Messaging Channel Capabilities](/docs/adding-messaging-channel-capabilities)  \n         * [Adding Actions & Triggers to Botpress Studio](/docs/adding-actions-triggers-to-botpress-studio)  \n         * [Publish your integration on Botpress Hub](/docs/publish-your-integration-on-botpress-hub)  \n   * [Use Your Own LLM](/docs/llm-interfaces)  \n   * [Connect a live agent platform with Botpress](/docs/hitl)  \n   * [Moving Parts](/docs/moving-parts)  \n   * [CLI](/docs/cli)  \n   * [SDK](/docs/sdk)  \n   * [Key Concepts](/docs/key-concepts)  \n         * [Architecture](/docs/architecture)\n/docs/sdk)  \n   * [Key Concepts](/docs/key-concepts)  \n         * [Architecture](/docs/architecture)  \n         * [Tags](/docs/tags)  \n         * [Channels](/docs/channels)  \n         * [Configuration](/docs/configuration)  \n         * [User](/docs/user)  \n         * [Conversations](/docs/conversations-1)  \n         * [Messages](/docs/messages)  \n         * [Event](/docs/event)  \n         * [States](/docs/states-1)  \n         * [Actions](/docs/actions)  \n         * [Definitions](/docs/definitions)  \n         * [Secrets](/docs/secrets)  \n         * [ZUI - Zod schema UI components in Botpress \\[BETA\\]](/docs/zui-zod-schema-ui-components-in-botpress)  \n   * [How to](/docs/states)  \n         * [States](/docs/states)  \n         * [Register & Unregister](/docs/register-unregister)  \n         * [Integrations Actions](/docs/integrations)  \n         * [Integration Events](/docs/integration-events)  \n         * [Handler](/docs/handler)  \n         * [Logging](/docs/logging)  \n         * [Building a Custom Integration](/docs/building-a-custom-integration)\n## Webchat\n* [Webchat](/docs/webchat)  \n   * [Webflow](/docs/webflow)  \n   * [Wix](/docs/wix)  \n   * [Wordpress](/docs/wordpress)\n* [Webchat v1 (deprecated)](/docs/web-chat-v1old)  \n   * [Controlling Web Chat using JavaScript](/docs/controlling-web-chat-using-javascript)  \n   * [Styling your webchat](/docs/chatbot-button)  \n         * [Chatbot Button](/docs/chatbot-button)  \n         * [Chat Header](/docs/chat-header)  \n         * [User Input Area](/docs/user-input-area)  \n         * [Show Bot Info](/docs/show-bot-info)  \n   * [Embedding Webchat](/docs/react-app)  \n         * [React App](/docs/react-app)  \n         * [React Native App](/docs/react-native-app)  \n         * [Web Chat Iframe](/docs/web-chat-iframe)  \n         * [Full Screen Chatbot](/docs/full-screen-chatbot)\n* [Webchat v2](/docs/embedded-webchat)  \n   * [Embedded Webchat](/docs/embedded-webchat)  \n         * [Custom CSS Reference](/docs/custom-css-reference)  \n   * [React Components](/docs/react-js)  \n   * [Webchat Client](/docs/webchat-client)\n## Botpress APIs\n* [Files API](/docs/files-api)\n* [Chat API](/docs/chat-api)\n## Appendix\n* [Safety](/docs/safety)  \n   * [Preventing Abuse](/docs/preventing-abuse)  \n   * [Brand Safety Framework](/docs/brand-safety-framework)\n* [Exporting Data](/docs/exporting-data)  \n   * [Raw Conversations](/docs/exporting-raw-conversations-with-the-botpress-api)  \n   * [Conversation History](/docs/getting-the-conversation-history-from-within-your-bot)  \n   * [Streaming Analytics](/docs/streaming-analytics-from-within-your-bot-with-hooks)  \n   * [Compiled Bot Analytics](/docs/exporting-compiled-bot-analytics-with-the-botpress-api)\nPowered by\n# Raw Conversations\n[ Suggest Edits](/edit/exporting-raw-conversations-with-the-botpress-api)\nThe 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!\n> ## ���\n>\n> Note\n>\n> Access the API documentation to verify the schema/structure of the [Conversations](https://botpress.com/docs/api-documentation/#schema%5Fconversation) and the [Messages](https://botpress.com/docs/api-documentation/#schema%5Fmessage) and see if the data is useful for your use case.\n> ## ���\n>\n> Note\n>\n> 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/`\n1\\. Getting the Conversations list from the API\n[](#1-getting-the-conversations-list-from-the-api)\nUsing Axios\n[](#using-axios)\nSend a `GET` request to `https://api.botpress.cloud/v1/chat/conversations` adding the following headers: `Authorization: Bearer <your-personal-access-token>` and `x-bot-id: <your-bot-id>`.\nThis is how the request would look like using Axios in a Javascript application (e.g in a Execute Code in Botpress):\nCoffeeScript\n`` const requestConfig = {\nheaders: {\n// Authorization header with a Bearer token for authentication.\nAuthorization: `Bearer ${process.env.BOTPRESS_PERSONAL_ACCESS_TOKEN}`,\n// The unique identifier of the bot for which we want to retrieve conversations.\n'x-bot-id': process.env.BOTPRESS_BOT_ID,\n},\n}\n// An empty array to store all retrieved conversations.\nconst allConversations = []\n// Send an HTTP GET request to the specified API endpoint to get conversations.\nconst getConversations = await axios.get(\n`https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,\nrequestConfig\n)\n// Add the retrieved conversations to the list.\nallConversations.push(...getConversations.data.conversations)\n``\nUsing the Botpress Client library\n[](#using-the-botpress-client-library)\nThe same logic to get conversations but using the [Botpress Client library](https://www.npmjs.com/package/@botpress/client) in a Node.js application:\nJavaScript\n`import { Client } from '@botpress/client'\nconst client = new Client({\ntoken: process.env.BOTPRESS_ACCESS_TOKEN,\nbotId: process.env.BOTPRESS_BOT_ID,\n})\nconst allConversations = []\nconst getConversations = await client.listConversations({\nnextToken: paginationToken,\n})\nallConversations.push(getConversations.conversations)\n`\n> ## ���\n>\n> Info\n>\n> 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.\n2\\. Getting all Conversations from the API\n[](#2-getting-all-conversations-from-the-api)\nNow 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 token regardless.\nGetting conversations gradually\n[](#getting-conversations-gradually)\nCreate 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. More about pagination [here](https://botpress.com/docs/api-documentation/#pagination).\nJavaScript\n`` async function loadConversations(paginationToken) {\nconst getConversations = await axios.get(\n`https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,\n{\n...requestConfig,\n}\n)\nreturn getConversations.data\n// The returned value will be an object: `{ conversations: [...], meta: { nextToken: \"string\" } }`\n}\n``\nGetting all conversations\n[](#getting-all-conversations)\nUse a loop to fetch all conversations at once using the above logic. This is not 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\n[p-retry](https://www.npmjs.com/package/p-retry) to retry requests automatically is recommended.\nJavaScript\n`` const allConversations = []\nlet paginationToken\ndo {\n// Send an HTTP GET request to the specified API endpoint to get conversations.\nconst getConversations = await axios.get(\n`https://api.botpress.cloud/v1/chat/conversations?nextToken=${paginationToken}`,\nrequestConfig\n)\n// Add the retrieved conversations to the list.\nallConversations.push(...getConversations.data.conversations)\n// Retrieve the token for the next set of conversations, if available.\npaginationToken = getConversations.data.meta.nextToken\n// As long as paginationToken has a value, this function will execute again\n} while (paginationToken)\n``\n3\\. Getting the Messages list\n[](#3-getting-the-messages-list)\nOnce 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.\nIn the example below we are using the [Botpress Client library](https://www.npmjs.com/package/@botpress/client) and assume the client is set up already:\nJavaScript\n`const conversationId = 'the desired conversation id here'\nconst allMessages = []\nconst getMessages = await client.listMessages({\nconversationId,\nnextToken: paginationToken,\n})\nallMessages.push(getMessages.messages)\n`\nYou might create a loader function or a finite loop as shown above to get all the messages.\nThis is how the `allMessages` array is gonna look like:\nJSON\n`[\n{\n\"id\": \"503dda87-3e54-40b6-8167-55d685a85345\",\n\"createdAt\": \"2023-10-24T20:20:44.812Z\",\n\"conversationId\": \"ec669jj8-e465-482d-8fbe-cb348bf81212\",\n\"payload\": {\n\"text\": \"Pick one or many from the list\",\n\"options\": [\n{\n\"label\": \"First option\",\n\"value\": \"First option\"\n},\n{\n\"label\": \"Second option\",\n\"value\": \"Second option\"\n}\n]\n},\n\"tags\": {},\n\"userId\": \"efc0f8e8-7e51-4458-8907-ea1e43eb8852\",\n\"type\": \"choice\",\n\"direction\": \"outgoing\"\n},\n{\n\"id\": \"41bb8564-e7ab-4113-c3d8-5fdhh27e4c34\",\n\"createdAt\": \"2023-10-24T20:20:49.201Z\",\n\"conversationId\": \"ec66ffb8-e465-482d-8fbe-csd348b81212\",\n\"payload\": {\n\"type\": \"quick_reply\",\n\"text\": \"First option\",\n\"payload\": \"First option\"\n},\n\"tags\": {\n\"webchat:id\": \"cc70c21b-4g24-4f5c-8f52-43a900b7b047\"\n},\n\"userId\": \"f96da97d-4215-447f-86e2-b9e33232e6d3\",\n\"type\": \"quick_reply\",\n\"direction\": \"incoming\"\n},\n{\n\"id\": \"c6ee8bd6-c862-54d2-97cb-998f555d4251\",\n\"createdAt\": \"2023-10-24T20:20:49.795Z\",\n\"conversationId\": \"ec669dd8-e465-482d-8fty-cb3348581212\",\n\"payload\": {\n\"imageUrl\": \"https://s3.us-east-1.amazonaws.com/cloud-studio-botsbca2d219-2316w6llinepa/f4b77ea0-d597-4d3f-988d-9c66f127d542/media/2360a7bb-162b-4ed1-8551-7000fdb0f7ef.png\"\n},\n\"tags\": {},\n\"userId\": \"efb454t5-7e51-4458-8007-ea1e43eb8852\",\n\"type\": \"image\",\n\"direction\": \"outgoing\"\n}\n]\n`\n> ## ���\n>\n> Note\n>\n> 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.\n4\\. Formatting the Messages list\n[](#4-formatting-the-messages-list)\nNow that you have the list of messages of a conversation it's time to format it so it becomes readable. We are going to use a custom function for that:\n`` function formatMessage(message) {\nlet messageText = ''\nif (message.direction === 'incoming') {\nmessageText += 'User: '\n} else {\nmessageText += 'Bot: '\n}\nif (message.type === 'text' || message.type === 'quick_reply') {\nmessageText += message.payload.text\n} else if (message.type === 'choice') {\nmessageText += `${message.payload.text}: ${message.payload.options.map((option) => option.label).join(' / ')}`\n} else {\nmessageText += `Media message of type ${message.type}`\n}\nmessageText += `\\n at ${new Date(message.createdAt).toLocaleString()}`\nreturn messageText\n}\nconst history = allMessages.map((message) => formatMessage(message)).join('\\n\\n')\n``\nThe `history` string will end up looking like this:\nText\n`Bot: Pick one or many from the list: First Option / Second Option\nat 24/10/2023, 5:20:44 PM\nUser: First Option\nat 24/10/2023, 5:21:00 PM\nBot: Media message of type image\nat 24/10/2023, 5:21:09 PM\n`\n> ## ���\n>\n> Note\n>\n> 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.\nUpdated about 1 month ago\n---\n* [Table of Contents](#)\n* * [1\\. Getting the Conversations list from the API](#1-getting-the-conversations-list-from-the-api)  \n         * [Using Axios](#using-axios)  \n         * [Using the Botpress Client library](#using-the-botpress-client-library)  \n   * [2\\. Getting all Conversations from the API](#2-getting-all-conversations-from-the-api)  \n         * [Getting conversations gradually](#getting-conversations-gradually)  \n         * [Getting all conversations](#getting-all-conversations)  \n   * [3\\. Getting the Messages list](#3-getting-the-messages-list)  \n   * [4\\. Formatting the Messages list](#4-formatting-the-messages-list)[Jump to Content](#content)\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\n---\n[![Botpress](https://files.readme.io/c8cb63b6d586cd66085b4c960570959a424c7050c5ffeb0aeaf31711e2e1b2ac-small-BPLOGO_new_dark_1.png)](https://botpress.com)\nGuides\nMoon (Dark Mode)Sun (Light Mode)\n[Guides](/docs)[API Reference](/reference)[Changelog](/changelog)\nFiles API\nSearch\n## Home\n* [Botpress Documentation](/docs/home)\n## Getting Started\n* [Build](/docs/build)\n* [Deploy](/docs/deploy)\n* [Monitor](/docs/monitor)\n## DASHBOARD\n* [Workspace](/docs/workspace)  \n   * [Home](/docs/home-1)  \n   * [Members](/docs/members)  \n   * [Audits](/docs/audits)  \n   * [Your integrations](/docs/your-integrations)  \n   * [Usage](/docs/usage-2)  \n   * [Settings](/docs/settings)  \n   * [Profile Setting](/docs/user-profile)\n* [Bot](/docs/bot)  \n   * [Overview](/docs/overview-1)  \n   * [Integrations](/docs/integrations-1)  \n   * [Webchat](/docs/webchat-1)  \n   * [Logs](/docs/logs)  \n   * [Conversations](/docs/conversations)  \n   * [Analytics](/docs/analytics-1)  \n   * [Events](/docs/events-2)  \n   * [Issues](/docs/issues)  \n   * [Configuration variables](/docs/configuration-variables-1)\n## STUDIO\n* [Interface](/docs/interface)  \n   * [Nodes](/docs/nodes)  \n   * [Home](/docs/home-2)  \n   * [Flows](/docs/studio-interface-flows)  \n   * [Knowledge Base](/docs/knowledge-base)  \n   * [Tables](/docs/tables)  \n   * [Agents](/docs/agents)  \n         * [Summary Agent](/docs/summary-agent)  \n         * [Personality Agent](/docs/personality-agent)  \n         * [Policy Agent](/docs/policy-agent)  \n         * [Translator Agent](/docs/translator-agent)  \n         * [Knowledge Agent](/docs/knowledge-agent)  \n         * [HITL Agent](/docs/hitl-agent)  \n         * [Vision Agent](/docs/vision-agent)  \n         * [Analytics Agent](/docs/analytics-agent)  \n   * [Library](/docs/library)  \n   * [Hooks](/docs/hooks)  \n   * [Integrations](/docs/integrations-3)  \n   * [Schemas](/docs/schemas)  \n   * [Card Hub](/docs/card-hub)  \n   * [Versions](/docs/versions-1)  \n   * [Chatbot Settings](/docs/chatbot-settings-1)  \n   * [Find](/docs/find)  \n   * [Variables](/docs/variables)  \n   * [Card Tray](/docs/card-tray)  \n   * [Debugger, Logs & JSON](/docs/debugger-logs-json)  \n   * [Emulator](/docs/emulator)  \n   * [Keyboard Shortcuts](/docs/keyboard-shortcuts)  \n   * [Commands](/docs/studio-commands)  \n   * [Studio Preferences](/docs/studio-preferences)  \n   * [Import & Export](/docs/import-export-bots)\n* [Cards](/docs/cards)  \n   * [Send Messages](/docs/send-messages)  \n   * [Execute](/\n<|end_input|>\n\nAnswer with this following format:\n```\n■is_about_animals:【explanation (where \"explanation\" is answering the question \"is the text about animals?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_lua_code:【explanation (where \"explanation\" is answering the question \"does the text contain Lua code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_python_code:【explanation (where \"explanation\" is answering the question \"does the text contain Python code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■contains_js_code:【explanation (where \"explanation\" is answering the question \"does the text contain JavaScript code?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_botpress:【explanation (where \"explanation\" is answering the question \"is the text about Botpress?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■is_rasa:【explanation (where \"explanation\" is answering the question \"is the text about Rasa?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_flows:【explanation (where \"explanation\" is answering the question \"does the text mention flows?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_api:【explanation (where \"explanation\" is answering the question \"does the text mention the Botpress API?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_enterprise:【explanation (where \"explanation\" is answering the question \"does the text mention Botpress Enterprise?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_workspaces:【explanation (where \"explanation\" is answering the question \"does the text mention workspaces?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_webchat:【explanation (where \"explanation\" is answering the question \"does the text mention the Webchat?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n\n■has_hitl:【explanation (where \"explanation\" is answering the question \"does the text mention HITL (human in the loop)?\")】:x■ (where x is ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES)\n■END■\n```\n\nFormat cheatsheet:\n```\n■label:【explanation】:x■\n```\n\nWhere `x` is one of the following: ABSOLUTELY_NOT | PROBABLY_NOT | AMBIGUOUS | PROBABLY_YES | ABSOLUTELY_YES\n\nRemember: In your `explanation`, please refer to the Expert Examples # (and quote them) that are relevant to ground your decision-making process.\nThe Expert Examples are there to help you make your decision. They have been provided by experts in the field and their answers (and reasoning) are considered the ground truth and should be used as a reference to make your decision when applicable.\nFor example, you can say: \"According to Expert Example #1, ...\"","role":"user","type":"text"}],"meta":{"integrationName":"zai","promptCategory":"zai:zai.label","promptSource":"zai:zai.label:default"},"model":"fast","signal":{},"stopSequences":["■END■"]},"method":"POST","url":"https://api.botpress.cloud/v2/cognitive/generate-text"}

Output:
■is_about_animals:【The text discusses Botpress HITL integration, code snippets, and platform navigation. There is no reference to animals at all.】:ABSOLUTELY_NOT■

■contains_lua_code:【All code shown is TypeScript/JavaScript (e.g., `import * as sdk from "@botpress/sdk";`, `await botpressClient.createEvent`). No Lua syntax or file extensions appear.】:ABSOLUTELY_NOT■

■contains_python_code:【The document contains only JavaScript/TypeScript examples and no Python (`def`, `import`, `.py`) code.】:ABSOLUTELY_NOT■

■contains_js_code:【The snippets are clearly JavaScript/TypeScript (e.g., `const requestConfig = { headers: { Authorization: … } }`, `await axios.get(...)`). This qualifies as JavaScript code.】:ABSOLUTELY_YES■

■is_botpress:【The entire article is about Botpress features – HITL integration, Botpress SDK, Botpress client library, and Botpress documentation links.】:ABSOLUTELY_YES■

■is_rasa:【No mention of Rasa, its APIs, or related terminology.】:ABSOLUTELY_NOT■

■has_flows:【The navigation includes a link to “Flows” (`* [Flows]` under Studio) and the text talks about “Flow Logic”.】:ABSOLUTELY_YES■

■has_api:【Multiple sections describe using the Botpress API (e.g., “Botpress API allows you to access your bot's conversations”, `client.listConversations`, `client.listMessages`).】:ABSOLUTELY_YES■

■has_enterprise:【The term “Enterprise” does not appear anywhere in the content.】:ABSOLUTELY_NOT■

■has_workspaces:【The sidebar lists “Workspace” (`* [Workspace]` under Dashboard) and the text references workspaces throughout the UI.】:ABSOLUTELY_YES■

■has_webchat:【There are extensive references to Webchat (“Webchat”, “Webchat v1”, “Webchat v2”, “Embedding Webchat”, etc.).】:ABSOLUTELY_YES■

■has_hitl:【The document is centered on HITL (Human‑in‑the‑Loop), with many occurrences of “hitl”, “HITL”, and related actions.】:ABSOLUTELY_YES■